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);
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph2->src));
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"respond new phase 2 negotiation: %s<=>%s\n",
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph2->dst));
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                   [iph2->side]
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                   [iph2->status])(iph2, msg);
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph1->remote,
1379c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to pre-process packet.\n");
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error != ISAKMP_INTERNAL_ERROR)
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_n1(iph2->ph1, error, NULL);
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * release handler because it's wrong that ph2handle is kept
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * after failed to check message for responder's.
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
1386c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		unbindph12(iph2);
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send */
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(isakmp->etype)]
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->side]
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->status])(iph2, msg) < 0) {
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1398c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to process packet.\n");
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't release handler */
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2",
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * parse ISAKMP payloads, without ISAKMP base header.
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_parsewoh(np0, gen, len)
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int np0;
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char np = np0 & 0xff;
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen, plen;
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *result;
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_parse_t *p, *ep;
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * 5 is a magic number, but any value larger than 2 should be fine
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * as we do vrealloc() in the following loop.
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	result = vmalloc(sizeof(struct isakmp_parse_t) * 5);
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (result == NULL) {
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer.\n");
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = (struct isakmp_parse_t *)result->v;
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ep = (struct isakmp_parse_t *)(result->v + result->l - sizeof(*ep));
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = len;
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* parse through general headers */
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (0 < tlen && np != ISAKMP_NPTYPE_NONE) {
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tlen <= sizeof(struct isakmp_gen)) {
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* don't send information, see isakmp_ident_r1() */
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid length of payload\n");
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(result);
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seen nptype=%u(%s)\n", np, s_isakmp_nptype(np));
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->type = np;
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->len = ntohs(gen->len);
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) {
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid length of payload\n");
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(result);
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->ptr = gen;
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p++;
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ep <= p) {
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int off;
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			off = p - (struct isakmp_parse_t *)result->v;
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = vrealloc(result, result->l * 2);
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (result == NULL) {
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to realloc buffer.\n");
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(result);
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return NULL;
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ep = (struct isakmp_parse_t *)
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(result->v + result->l - sizeof(*ep));
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = (struct isakmp_parse_t *)result->v;
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += off;
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		np = gen->np;
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = ntohs(gen->len);
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gen = (struct isakmp_gen *)((caddr_t)gen + plen);
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen -= plen;
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->type = ISAKMP_NPTYPE_NONE;
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->len = 0;
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->ptr = NULL;
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "succeed.\n");
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return result;
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * parse ISAKMP payloads, including ISAKMP base header.
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_parse(buf)
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)buf->v;
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *result;
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char np;
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	np = isakmp->np;
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen = (struct isakmp_gen *)(buf->v + sizeof(*isakmp));
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = buf->l - sizeof(struct isakmp);
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	result = isakmp_parsewoh(np, gen, tlen);
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return result;
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%% */
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_init()
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize a isakmp status table */
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initph1tree();
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initph2tree();
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initctdtree();
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	init_recvdpkt();
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1529c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (isakmp_open() < 0)
1530c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		goto err;
1531c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1532c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(0);
1533c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1534c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeherr:
1535c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	isakmp_close();
1536c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(-1);
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make strings containing i_cookie + r_cookie + msgid
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char *
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_pindex(index, msgid)
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const isakmp_index *index;
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_int32_t msgid;
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char buf[64];
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_char *p;
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i, j;
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(buf, 0, sizeof(buf));
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy index */
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = (const u_char *)index;
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		j += 2;
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (i) {
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 7:
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf[j++] = ':';
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msgid == 0)
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return buf;
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy msgid */
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	snprintf((char *)&buf[j], sizeof(buf) - j, ":%08x", ntohs(msgid));
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* open ISAKMP sockets. */
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1575c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehisakmp_open()
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int yes = 1;
1578c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int ifnum = 0, encap_ifnum = 0;
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pktinfo;
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1582c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct myaddrs *p;
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1584c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	for (p = lcconf->myaddrs; p; p = p->next) {
1585c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (!p->addr)
1586c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			continue;
1587c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1588c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* warn if wildcard address - should we forbid this? */
1589c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		switch (p->addr->sa_family) {
1590c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case AF_INET:
1591c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (((struct sockaddr_in *)p->addr)->sin_addr.s_addr == 0)
1592c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				plog(LLV_WARNING, LOCATION, NULL,
1593c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					"listening to wildcard address,"
1594c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					"broadcast IKE packet may kill you\n");
1595c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
1597c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case AF_INET6:
1598c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)p->addr)->sin6_addr))
1599c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				plog(LLV_WARNING, LOCATION, NULL,
1600c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					"listening to wildcard address, "
1601c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					"broadcast IKE packet may kill you\n");
1602c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
1603c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1604c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		default:
1605c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
1606c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"unsupported address family %d\n",
1607c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				lcconf->default_af);
1608c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			goto err_and_next;
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1611c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6
1612c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (p->addr->sa_family == AF_INET6 &&
1613c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)
1614c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					    p->addr)->sin6_addr))
1615c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		{
1616c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_DEBUG, LOCATION, NULL,
1617c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"Ignoring multicast address %s\n",
1618c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				saddr2str(p->addr));
1619c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				racoon_free(p->addr);
1620c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				p->addr = NULL;
1621c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			continue;
1622c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
1623f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1625c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if ((p->sock = socket(p->addr->sa_family, SOCK_DGRAM, 0)) < 0) {
1626f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
1627c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"socket (%s)\n", strerror(errno));
1628c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			goto err_and_next;
1629f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		}
1630f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1631c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
1632f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			plog(LLV_WARNING, LOCATION, NULL,
1633c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"failed to put socket in non-blocking mode\n");
1634f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1635c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* receive my interface address on inbound packets. */
1636c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		switch (p->addr->sa_family) {
1637c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case AF_INET:
1638c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (setsockopt(p->sock, IPPROTO_IP,
1639c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef __linux__
1640c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				       IP_PKTINFO,
1641c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
1642c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				       IP_RECVDSTADDR,
1643c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1644c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					(const void *)&yes, sizeof(yes)) < 0) {
1645c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				plog(LLV_ERROR, LOCATION, NULL,
1646c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					"setsockopt IP_RECVDSTADDR (%s)\n",
1647c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					strerror(errno));
1648c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto err_and_next;
1649c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
1650c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
1652c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case AF_INET6:
1653c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6_ADVAPI
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef IPV6_RECVPKTINFO
1655c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			pktinfo = IPV6_RECVPKTINFO;
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else  /* old adv. API */
1657c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			pktinfo = IPV6_PKTINFO;
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* IPV6_RECVPKTINFO */
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
1660c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			pktinfo = IPV6_RECVDSTADDR;
1661c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1662c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (setsockopt(p->sock, IPPROTO_IPV6, pktinfo,
1663c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					(const void *)&yes, sizeof(yes)) < 0)
1664c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			{
1665c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				plog(LLV_ERROR, LOCATION, NULL,
1666c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					"setsockopt IPV6_RECVDSTADDR (%d):%s\n",
1667c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					pktinfo, strerror(errno));
1668c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto err_and_next;
1669c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
1670c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef IPV6_USE_MIN_MTU
1675c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (p->addr->sa_family == AF_INET6 &&
1676c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
1677c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    (void *)&yes, sizeof(yes)) < 0) {
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
1679c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    "setsockopt IPV6_USE_MIN_MTU (%s)\n",
1680c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    strerror(errno));
1681c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return -1;
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1684c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1685c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (setsockopt_bypass(p->sock, p->addr->sa_family) < 0)
1686c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			goto err_and_next;
1687c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1688c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (bind(p->sock, p->addr, sysdep_sa_len(p->addr)) < 0) {
1689c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, p->addr,
1690c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"failed to bind to address %s (%s).\n",
1691c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				saddr2str(p->addr), strerror(errno));
1692c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			close(p->sock);
1693c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			goto err_and_next;
1694c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
1695c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1696c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ifnum++;
1697c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1698c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_INFO, LOCATION, NULL,
1699c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"%s used as isakmp port (fd=%d)\n",
1700c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			saddr2str(p->addr), p->sock);
1701c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1702c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_NATT
1703c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (p->addr->sa_family == AF_INET) {
1704c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			int option = -1;
1705c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1706c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1707c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if(p->udp_encap)
1708c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				option = UDP_ENCAP_ESPINUDP;
1709c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01)
1710c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			else
1711c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				option = UDP_ENCAP_ESPINUDP_NON_IKE;
1712c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1713c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if(option != -1){
1714c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (setsockopt (p->sock, SOL_UDP,
1715c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    UDP_ENCAP, &option, sizeof (option)) < 0) {
1716c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					plog(LLV_WARNING, LOCATION, NULL,
1717c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					    "setsockopt(%s): UDP_ENCAP %s\n",
1718c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					    option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
1719c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						 strerror(errno));
1720c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					goto skip_encap;
1721c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				}
1722c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				else {
1723c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					plog(LLV_INFO, LOCATION, NULL,
1724c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						 "%s used for NAT-T\n",
1725c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						 saddr2str(p->addr));
1726c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					encap_ifnum++;
1727c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				}
1728c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
1729c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
1730c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehskip_encap:
17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1732c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		continue;
1733c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1734c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	err_and_next:
1735c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		racoon_free(p->addr);
1736c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		p->addr = NULL;
1737c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (! lcconf->autograbaddr && lcconf->strict_address)
1738c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return -1;
1739c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		continue;
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1742c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (!ifnum) {
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1744c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"no address could be bound.\n");
1745c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1748c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_NATT
1749c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (natt_enabled_in_rmconf() && !encap_ifnum) {
1750c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_WARNING, LOCATION, NULL,
1751c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"NAT-T is enabled in at least one remote{} section,\n");
1752c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_WARNING, LOCATION, NULL,
1753c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"but no 'isakmp_natt' address was specified!\n");
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1755c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1757c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return 0;
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
1761c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehisakmp_close()
17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1763c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef ANDROID_PATCHED
1764c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct myaddrs *p, *next;
1765c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1766c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	for (p = lcconf->myaddrs; p; p = next) {
1767c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		next = p->next;
1768c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1769c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (!p->addr) {
1770c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			racoon_free(p);
1771c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			continue;
1772c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
1773c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		close(p->sock);
1774c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		racoon_free(p->addr);
1775c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		racoon_free(p);
1776c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1777c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1778c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	lcconf->myaddrs = NULL;
1779c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_send(iph1, sbuf)
17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sbuf;
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int s;
17891c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	vchar_t *vbuf = NULL, swap;
17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0;
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17941c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	/* Check if NON_ESP_MARKER_LEN is already there (happens when resending packets)
17951c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	 */
17961c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	if(extralen == NON_ESP_MARKER_LEN &&
17971c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	   *(u_int32_t *)sbuf->v == 0)
17981c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		extralen = 0;
17991c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
1801c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Do not add the non ESP marker for a packet that will
1803c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * be fragmented. The non ESP marker should appear in
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * all fragment's packets, but not in the fragmented packet
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
1806c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN)
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		extralen = 0;
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extralen)
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1812c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
1813c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	   must added just before the packet itself. For this we must
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   allocate a new buffer and release it at the end. */
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extralen) {
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) {
1817c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
18180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "vbuf allocation failed\n");
18190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*(u_int32_t *)vbuf->v = 0;
18220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy (vbuf->v + extralen, sbuf->v, sbuf->l);
18231c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		/* ensures that the modified buffer will be sent back to the caller, so
18241c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * add_recvdpkt() will add the correct buffer
18251c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 */
18261c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		swap = *sbuf;
18271c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		*sbuf = *vbuf;
18281c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		*vbuf = swap;
18291c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		vfree(vbuf);
18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* select the socket to be sent */
1834c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	s = getsockmyaddr(iph1->local);
1835c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (s == -1){
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1837c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1839c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l,
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	      saddr2str_fromto("from %s to %s", iph1->local, iph1->remote));
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) {
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_sendfrags(iph1, sbuf) == -1) {
1845c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "isakmp_sendfrags failed\n");
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1849c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	} else
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = sendfromto(s, sbuf->v, sbuf->l,
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    iph1->local, iph1->remote, lcconf->count_persend);
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (len == -1) {
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
18610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
18620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
1865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1resend_stub(p)
1867c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1869c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct ph1handle *iph1;
1870c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1871c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1=(struct ph1handle *)p;
1872c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if(isakmp_ph1resend(iph1) < 0){
1873c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if(iph1->scr != NULL){
1874c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			/* Should not happen...
1875c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			 */
1876c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			sched_kill(iph1->scr);
1877c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			iph1->scr=NULL;
1878c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1885c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1resend(iph1)
18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function
18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->retry_counter <= 0) {
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase1 negotiation failed due to time up. %s\n",
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_pindex(&iph1->index, iph1->msgid));
1895c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		EVT_PUSH(iph1->local, iph1->remote,
1896c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    EVTT_PEER_NO_RESPONSE, NULL);
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_send(iph1, iph1->sendbuf) < 0){
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "phase1 negotiation failed due to send error. %s\n",
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 isakmp_pindex(&iph1->index, iph1->msgid));
1905c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		EVT_PUSH(iph1->local, iph1->remote,
1906c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				 EVTT_PEER_NO_RESPONSE, NULL);
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"resend phase1 packet %s\n",
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_pindex(&iph1->index, iph1->msgid));
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->retry_counter--;
19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1916c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1->scr = sched_new(iph1->rmconf->retry_interval,
1917c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		isakmp_ph1resend_stub, iph1);
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
1923c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2resend_stub(p)
1925c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1927c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct ph2handle *iph2;
1928c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1929c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2=(struct ph2handle *)p;
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1931c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if(isakmp_ph2resend(iph2) < 0){
1932c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		unbindph12(iph2);
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1938c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2resend(iph2)
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
1944c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->ph1->status == PHASE1ST_EXPIRED){
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed due to phase1 expired. %s\n",
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->retry_counter <= 0) {
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed due to time up. %s\n",
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1955c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2);
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed due to send error. %s\n",
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1964c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
1965c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"resend phase2 packet %s\n",
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_pindex(&iph2->ph1->index, iph2->msgid));
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->retry_counter--;
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1975c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->scr = sched_new(iph2->ph1->rmconf->retry_interval,
1976c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		isakmp_ph2resend_stub, iph2);
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1981f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh/* called from scheduler */
1982f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehvoid
1983f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehisakmp_ph1expire_stub(p)
1984c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
1985f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{
1986c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1987c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	isakmp_ph1expire((struct ph1handle *)p);
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1expire(iph1)
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1996c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph1->sce);
1997c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1998c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if(iph1->status != PHASE1ST_EXPIRED){
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = racoon_strdup(saddr2str(iph1->local));
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = racoon_strdup(saddr2str(iph1->remote));
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(src);
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(dst);
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "ISAKMP-SA expired %s-%s spi:%s\n",
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 src, dst,
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 isakmp_pindex(&iph1->index, 0));
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(src);
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(dst);
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->status = PHASE1ST_EXPIRED;
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2013c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
2014c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * the phase1 deletion is postponed until there is no phase2.
2015c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 */
2016c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
2017c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1->sce = sched_new(1, isakmp_ph1expire_stub, iph1);
2018c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return;
2019c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
2020c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2021c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1delete_stub(p)
2027c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2030c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	isakmp_ph1delete((struct ph1handle *)p);
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1delete(iph1)
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2039c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph1->sce);
2040c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2041c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
2042c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
2043c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return;
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2046c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* don't re-negosiation when the phase 1 SA expires. */
2047c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddr2str(iph1->local));
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddr2str(iph1->remote));
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"ISAKMP-SA deleted %s-%s spi:%s\n",
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src, dst, isakmp_pindex(&iph1->index, 0));
2056c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph1(iph1);
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph1(iph1);
2062c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2063c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return;
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler.
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function will call only isakmp_ph2delete().
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * phase 2 handler remain forever if kernel doesn't cry a expire of phase 2 SA
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * by something cause.  That's why this function is called after phase 2 SA
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * expires in the userland.
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2expire_stub(p)
2074c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2077c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	isakmp_ph2expire((struct ph2handle *)p);
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2expire(iph2)
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2086c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->sce);
2087c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddrwop2str(iph2->src));
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddrwop2str(iph2->dst));
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2 sa expired %s-%s\n", src, dst);
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_EXPIRED;
2099c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2100c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
2101c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2102c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return;
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2delete_stub(p)
2108c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2111c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	isakmp_ph2delete((struct ph2handle *)p);
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2delete(iph2)
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2120c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->sce);
2121c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddrwop2str(iph2->src));
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddrwop2str(iph2->dst));
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2 sa deleted %s-%s\n", src, dst);
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	unbindph12(iph2);
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%%
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Interface between PF_KEYv2 and ISAKMP
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive ACQUIRE from kernel, and begin either phase1 or phase2.
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * if phase1 has been finished, begin phase2.
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
2147c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehisakmp_post_acquire(iph2)
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1 = NULL;
2152c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n");
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2155c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* search appropreate configuration with masking port. */
2156c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	rmconf = getrmconf(iph2->dst);
2157c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (rmconf == NULL) {
2158c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
2159c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"no configuration found for %s.\n",
2160c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			saddrwop2str(iph2->dst));
2161c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* if passive mode, ignore the acquire message */
2165c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (rmconf->passive) {
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because of passive mode, "
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore the acquire message for %s.\n",
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddrwop2str(iph2->dst));
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2173c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
2174c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * Search isakmp status table by address and port
2175c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * If NAT-T is in use, consider null ports as a
2176c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * wildcard and use IKE ports instead.
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
2178c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_NATT
2179c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
2180c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
2181c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(iph2->src, extract_port(iph1->local));
2182c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(iph2->dst, extract_port(iph1->remote));
2183c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
2184c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	} else {
2185c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
2186c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
2187c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
2188c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
2189c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no ISAKMP-SA found. */
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL) {
2193c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct sched *sc;
2194c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->retry_checkph1 = lcconf->retry_checkph1;
2196c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sc = sched_new(1, isakmp_chkph1there_stub, iph2);
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"IPsec-SA request for %s queued "
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"due to no phase1 found.\n",
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddrwop2str(iph2->dst));
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* start phase 1 negotiation as a initiator. */
2203c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) < 0) {
2204c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			SCHED_KILL(sc);
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*NOTREACHED*/
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found ISAKMP-SA, but on negotiation. */
2213c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph1->status != PHASE1ST_ESTABLISHED) {
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->retry_checkph1 = lcconf->retry_checkph1;
2215c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sched_new(1, isakmp_chkph1there_stub, iph2);
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, iph2->dst,
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"request for establishing IPsec-SA was queued "
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"due to no phase1 found.\n");
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*NOTREACHED*/
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found established ISAKMP-SA */
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* i.e. iph1->status == PHASE1ST_ESTABLISHED */
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found ISAKMP-SA. */
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* begin quick mode */
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_ph2begin_i(iph1, iph2))
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive GETSPI from kernel.
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_post_getspi(iph2)
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* don't process it because there is no suitable phase1-sa. */
2248c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->ph1->status == PHASE1ST_EXPIRED) {
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"the negotiation is stopped, "
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because there is no suitable ISAKMP-SA.\n");
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph2->side]
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph2->status])(iph2, NULL) != 0)
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2",
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called by scheduler */
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_chkph1there_stub(p)
2276c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2278c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	isakmp_chkph1there((struct ph2handle *)p);
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_chkph1there(iph2)
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->retry_checkph1--;
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->retry_checkph1 < 0) {
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->dst,
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed "
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"due to time up waiting for phase1. %s\n",
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(iph2->dst, iph2->src,
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph2->satype, 0, 0));
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"delete phase 2 handler.\n");
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* send acquire to kernel as error */
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pk_sendeacquire(iph2);
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2300c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		unbindph12(iph2);
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2307c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
2308c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * Search isakmp status table by address and port
2309c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * If NAT-T is in use, consider null ports as a
2310c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * wildcard and use IKE ports instead.
2311c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 */
2312c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_NATT
2313c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
2314c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: extract_port.\n");
2315c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if( (iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL){
2316c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found a ph1 wop.\n");
2317c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
2318c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	} else {
2319c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: searching byaddr.\n");
2320c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
2321c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if(iph1 != NULL)
2322c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found byaddr.\n");
2323c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
2324c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
2326c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX Even if ph1 as responder is there, should we not start
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * phase 2 negotiation ? */
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 != NULL
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 && iph1->status == PHASE1ST_ESTABLISHED) {
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* found isakmp-sa */
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local));
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote));
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "before:\n");
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph2->src, extract_port(iph1->local));
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph2->dst, extract_port(iph1->remote));
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "After:\n");
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* begin quick mode */
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)isakmp_ph2begin_i(iph1, iph2);
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no isakmp-sa found */
2354c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	sched_new(1, isakmp_chkph1there_stub, iph2);
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* copy variable data into ALLOCATED buffer. */
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_set_attr_v(buf, type, val, len)
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t val;
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)buf;
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)len);
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data + 1, val, len);
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf + sizeof(*data) + len;
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* copy fixed length data into ALLOCATED buffer. */
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_set_attr_l(buf, type, val)
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t val;
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)buf;
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)val);
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf + sizeof(*data);
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* add a variable data attribute to the buffer by reallocating it. */
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_add_attr_v(buf0, type, val, len)
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf0;
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t val;
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int oldlen = 0;
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sizeof(*data) + len;
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf0) {
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		oldlen = buf0->l;
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vrealloc(buf0, oldlen + tlen);
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vmalloc(tlen);
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get a attribute buffer.\n");
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)(buf->v + oldlen);
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)len);
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data + 1, val, len);
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* add a fixed data attribute to the buffer by reallocating it. */
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_add_attr_l(buf0, type, val)
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf0;
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t val;
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int oldlen = 0;
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sizeof(*data);
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf0) {
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		oldlen = buf0->l;
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vrealloc(buf0, oldlen + tlen);
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vmalloc(tlen);
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get a attribute buffer.\n");
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)(buf->v + oldlen);
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)val);
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * calculate cookie and set.
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_newcookie(place, remote, local)
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t place;
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote;
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *local;
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL, *buf2 = NULL;
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *p;
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int blen;
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int alen;
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t sa1, sa2;
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	time_t t;
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_short port;
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (remote->sa_family != local->sa_family) {
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"address family mismatch, remote:%d local:%d\n",
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remote->sa_family, local->sa_family);
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (remote->sa_family) {
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET:
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		alen = sizeof(struct in_addr);
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa1 = (caddr_t)&((struct sockaddr_in *)remote)->sin_addr;
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa2 = (caddr_t)&((struct sockaddr_in *)local)->sin_addr;
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET6:
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		alen = sizeof(struct in6_addr);
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa1 = (caddr_t)&((struct sockaddr_in6 *)remote)->sin6_addr;
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa2 = (caddr_t)&((struct sockaddr_in6 *)local)->sin6_addr;
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid family: %d\n", remote->sa_family);
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen = (alen + sizeof(u_short)) * 2
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		+ sizeof(time_t) + lcconf->secret_size;
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = vmalloc(blen);
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL) {
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get a cookie.\n");
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = buf->v;
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy my address */
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, sa1, alen);
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += alen;
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port = ((struct sockaddr_in *)remote)->sin_port;
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, &port, sizeof(u_short));
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(u_short);
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy target address */
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, sa2, alen);
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += alen;
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port = ((struct sockaddr_in *)local)->sin_port;
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, &port, sizeof(u_short));
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(u_short);
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy time */
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	t = time(0);
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, (caddr_t)&t, sizeof(t));
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(t);
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy random value */
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf2 = eay_set_random(lcconf->secret_size);
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf2 == NULL)
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, buf2->v, lcconf->secret_size);
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += lcconf->secret_size;
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(buf2);
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf2 = eay_sha1_one(buf);
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(place, buf2->v, sizeof(cookie_t));
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa1 = val2str(place, sizeof (cookie_t));
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "new cookie:\n%s\n", sa1);
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(sa1);
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf2 != NULL)
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf2);
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * save partner's(payload) data into phhandle.
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_p2ph(buf, gen)
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **buf;
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX to be checked in each functions for logging. */
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*buf) {
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore this payload, same payload type exist.\n");
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*buf = vmalloc(ntohs(gen->len) - sizeof(*gen));
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*buf == NULL) {
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer.\n");
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy((*buf)->v, gen + 1, (*buf)->l);
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_newmsgid2(iph1)
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t msgid2;
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	do {
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msgid2 = eay_random();
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} while (getph2bymsgid(iph1, msgid2));
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return msgid2;
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp header for phase 1
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic caddr_t
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid)
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vbuf;
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t etype;
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t flags;
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t msgid;
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp;
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (vbuf->l < sizeof(*isakmp))
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp = (struct isakmp *)vbuf->v;
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->np = nptype;
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->v = iph1->version;
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->etype = etype;
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->flags = flags;
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->msgid = msgid;
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->len = htonl(vbuf->l);
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return vbuf->v + sizeof(*isakmp);
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp header for phase 1
26270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_header1(vbuf, iph1, nptype)
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vbuf;
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid);
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp header for phase 2
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_header2(vbuf, iph2, nptype)
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vbuf;
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid);
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp payload.
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_payload(buf, src, nptype)
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src;
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "add payload of len %zu, next type %d\n",
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    src->l, nptype);
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen = (struct isakmp_gen *)p;
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen->np = nptype;
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen->len = htons(sizeof(*gen) + src->l);
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(*gen);
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, src->v, src->l);
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += src->l;
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return p;
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangetypesw1(etype)
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int etype;
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (etype) {
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_IDENT:
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_AGG:
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 2;
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_BASE:
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 3;
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangetypesw2(etype)
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int etype;
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (etype) {
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_QUICK:
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* for print-isakmp.c */
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *snapend;
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangextern void isakmp_print __P((const u_char *, u_int, const u_char *));
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *getname __P((const u_char *));
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *getname6 __P((const u_char *));
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint safeputchar __P((int));
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return a name for the IP address pointed to by ap.  This address
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is assumed to be in network byte order.
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetname(ap)
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_char *ap;
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in addr;
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char ntop_buf[NI_MAXHOST];
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&addr, 0, sizeof(addr));
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin_len = sizeof(struct sockaddr_in);
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin_family = AF_INET;
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&addr.sin_addr, ap, sizeof(addr.sin_addr));
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getnameinfo((struct sockaddr *)&addr, sizeof(addr),
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ntop_buf, sizeof(ntop_buf), NULL, 0,
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NI_NUMERICHOST | niflags))
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strlcpy(ntop_buf, "?", sizeof(ntop_buf));
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ntop_buf;
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return a name for the IP6 address pointed to by ap.  This address
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is assumed to be in network byte order.
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetname6(ap)
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_char *ap;
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in6 addr;
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char ntop_buf[NI_MAXHOST];
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&addr, 0, sizeof(addr));
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin6_len = sizeof(struct sockaddr_in6);
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin6_family = AF_INET6;
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&addr.sin6_addr, ap, sizeof(addr.sin6_addr));
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getnameinfo((struct sockaddr *)&addr, addr.sin6_len,
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ntop_buf, sizeof(ntop_buf), NULL, 0,
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NI_NUMERICHOST | niflags))
27590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strlcpy(ntop_buf, "?", sizeof(ntop_buf));
27600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ntop_buf;
27620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* INET6 */
27640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
27660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsafeputchar(c)
27670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int c;
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned char ch;
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ch = (unsigned char)(c & 0xff);
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (c < 0x80 && isprint(c))
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return printf("%c", c & 0xff);
27740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return printf("\\%03o", c & 0xff);
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
27790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_printpacket(msg, from, my, decoded)
27800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *from;
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *my;
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int decoded;
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef YIPS_DEBUG
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval tv;
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int s;
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char hostbuf[NI_MAXHOST];
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char portbuf[NI_MAXSERV];
27900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp;
27910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (loglevel < LLV_DEBUG)
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef YIPS_DEBUG
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&tv, NULL);
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	s = tv.tv_sec % 3600;
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf("%02d:%02d.%06u ", s / 60, s % 60, (u_int32_t)tv.tv_usec);
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (from) {
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (getnameinfo(from, sysdep_sa_len(from), hostbuf, sizeof(hostbuf),
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				portbuf, sizeof(portbuf),
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(hostbuf, "?", sizeof(hostbuf));
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(portbuf, "?", sizeof(portbuf));
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("%s:%s", hostbuf, portbuf);
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("?");
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf(" -> ");
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (my) {
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (getnameinfo(my, sysdep_sa_len(my), hostbuf, sizeof(hostbuf),
28170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				portbuf, sizeof(portbuf),
28180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
28190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(hostbuf, "?", sizeof(hostbuf));
28200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(portbuf, "?", sizeof(portbuf));
28210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("%s:%s", hostbuf, portbuf);
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("?");
28250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf(": ");
28260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = vdup(msg);
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
28290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("(malloc fail)\n");
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
28310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (decoded) {
28330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp = (struct isakmp *)buf->v;
28340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->flags & ISAKMP_FLAG_E) {
28350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
28360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int pad;
28370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pad = *(u_char *)(buf->v + buf->l - 1);
28380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (buf->l < pad && 2 < vflag)
28390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				printf("(wrong padding)");
28400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
28410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp->flags &= ~ISAKMP_FLAG_E;
28420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	snapend = buf->v + buf->l;
28460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_print(buf->v, buf->l, NULL);
28470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(buf);
28480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf("\n");
28490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fflush(stdout);
28500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
28520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
28530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /*HAVE_PRINT_ISAKMP_C*/
28550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
28570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcopy_ph1addresses(iph1, rmconf, remote, local)
28580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
28590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
28600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
28610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t port;
28630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* address portion must be grabbed from real remote address "remote" */
28650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->remote = dupsaddr(remote);
28660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->remote == NULL)
28670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
28680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
28700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * if remote has no port # (in case of initiator - from ACQUIRE msg)
28710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * - if remote.conf specifies port #, use that
28720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * - if remote.conf does not, use 500
28730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * if remote has port # (in case of responder - from recvfrom(2))
28740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * respect content of "remote".
28750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
28760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port(iph1->remote) == 0) {
2877c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		port = extract_port(rmconf->remote);
28780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (port == 0)
28790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			port = PORT_ISAKMP;
28800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph1->remote, port);
28810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (local == NULL)
28840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->local = getlocaladdr(iph1->remote);
28850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
28860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->local = dupsaddr(local);
28870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->local == NULL)
28880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
28890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2890c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (extract_port(iph1->local) == 0)
28910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph1->local, PORT_ISAKMP);
28920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
28940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port(iph1->local) == lcconf->port_isakmp_natt) {
28950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n");
28960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER;
28970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
28990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
29010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
29040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnostate1(iph1, msg)
29050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
29060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
29070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, iph1->remote, "wrong state %u.\n",
29090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->status);
29100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
29110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
29140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnostate2(iph2, msg)
29150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
29160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
29170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "wrong state %u.\n",
29190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->status);
29200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
29210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
29240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanglog_ph1established(iph1)
29250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct ph1handle *iph1;
29260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
29280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddr2str(iph1->local));
29300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddr2str(iph1->remote));
29310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
29320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
29330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
29350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"ISAKMP-SA established %s-%s spi:%s\n",
29360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src, dst,
29370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_pindex(&iph1->index, 0));
2938c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2939c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
29400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(!iph1->rmconf->mode_cfg)
2941c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
29420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
29440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
29450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
29470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct payload_list *
2950c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehisakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_type)
29510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (! plist) {
29530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist = racoon_malloc (sizeof (struct payload_list));
29540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist->prev = NULL;
29550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else {
29570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist->next = racoon_malloc (sizeof (struct payload_list));
29580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist->next->prev = plist;
29590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist = plist->next;
29600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plist->next = NULL;
29630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plist->payload = payload;
29640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plist->payload_type = payload_type;
29650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return plist;
29670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2969c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvchar_t *
29700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
29710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct payload_list *ptr = *plist, *first;
29730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t tlen = sizeof (struct isakmp), n = 0;
29740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
29750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *p;
29760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Seek to the first item.  */
29780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (ptr->prev) ptr = ptr->prev;
29790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	first = ptr;
2980c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
29810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Compute the whole length.  */
29820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (ptr) {
29830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen += ptr->payload->l + sizeof (struct isakmp_gen);
29840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ptr = ptr->next;
29850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = vmalloc(tlen);
29880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL) {
29890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
29900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer to send.\n");
29910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
29920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ptr = first;
29950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = set_isakmp_header1(buf, iph1, ptr->payload_type);
29970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
29980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
29990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (ptr)
30010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
30020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE);
30030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		first = ptr;
30040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ptr = ptr->next;
30050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free (first);
30060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ptr->prev = NULL; first = NULL; ... omitted.  */
30070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n++;
30080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*plist = NULL;
30110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
30130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
30140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
30150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
30160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
30170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
30180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
3020c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
30210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfrag_handler(iph1, msg, remote, local)
30220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
30230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
30240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote;
30250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *local;
30260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
30270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newmsg;
30280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_frag_extract(iph1, msg) == 1) {
30300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
3031c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, remote,
30320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Packet reassembly failed\n");
30330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
30340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return isakmp_main(newmsg, remote, local);
30360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
30390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
30400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
30430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangscript_hook(iph1, script)
30440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
30450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int script;
30460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
30470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define IP_MAX 40
30480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define PORT_MAX 6
30490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char addrstr[IP_MAX];
30500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char portstr[PORT_MAX];
30510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **envp = NULL;
30520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int envc = 1;
3053c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr_in *sin;
30540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **c;
30550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL ||
30570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->rmconf == NULL ||
30580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->rmconf->script[script] == NULL)
30590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
30600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
30620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)isakmp_cfg_setenv(iph1, &envp, &envc);
30630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* local address */
3066c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	sin = (struct sockaddr_in *)iph1->local;
3067c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
3068c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
30690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) {
30710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n");
30720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
30730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (script_env_append(&envp, &envc, "LOCAL_PORT", portstr) != 0) {
30760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_PORT\n");
30770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
30780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Peer address */
30810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->remote != NULL) {
3082c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sin = (struct sockaddr_in *)iph1->remote;
3083c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
3084c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
30850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (script_env_append(&envp, &envc,
30870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "REMOTE_ADDR", addrstr) != 0) {
30880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
30890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot set REMOTE_ADDR\n");
30900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
30910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (script_env_append(&envp, &envc,
30940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "REMOTE_PORT", portstr) != 0) {
30950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
30960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot set REMOTEL_PORT\n");
30970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
30980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_script_exec(iph1->rmconf->script[script]->v,
31020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    script, envp) != 0)
31030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Script %s execution failed\n", script_names[script]);
31050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
31070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (c = envp; *c; c++)
31080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(*c);
31090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(envp);
31110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
31130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangscript_env_append(envp, envc, name, value)
31170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char ***envp;
31180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *envc;
31190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *name;
31200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *value;
31210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *envitem;
31230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **newenvp;
31240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int newenvc;
31250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	envitem = racoon_malloc(strlen(name) + 1 + strlen(value) + 1);
31270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (envitem == NULL) {
31280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
31300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sprintf(envitem, "%s=%s", name, value);
31330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvc = (*envc) + 1;
31350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvp = racoon_realloc(*envp, newenvc * sizeof(char *));
31360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newenvp == NULL) {
31370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
31390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(envitem);
31400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvp[newenvc - 2] = envitem;
31440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvp[newenvc - 1] = NULL;
31450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*envp = newenvp;
31470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*envc = newenvc;
31480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
31490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangscript_exec(script, name, envp)
31530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *script;
31540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int name;
31550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const envp[];
31560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *argv[] = { NULL, NULL, NULL };
31580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	argv[0] = script;
31600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	argv[1] = script_names[name];
31610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	argv[2] = NULL;
31620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3163c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	switch (fork()) {
31640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0:
31650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		execve(argv[0], argv, envp);
31660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "execve(\"%s\") failed: %s\n",
31680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    argv[0], strerror(errno));
31690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		_exit(1);
31700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
31710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case -1:
31720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot fork: %s\n", strerror(errno));
31740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
31760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
31770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3178c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
31790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
31800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
31840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpurge_remote(iph1)
31850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
31860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
31880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg, *next, *end;
31890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
31900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
31910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t mhp[SADB_EXT_MAX + 1];
31920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id;
31930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
31940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *new_iph1;
31950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
31970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "purging ISAKMP-SA spi=%s.\n",
31980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 isakmp_pindex(&(iph1->index), iph1->msgid));
31990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Mark as expired. */
32010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->status = PHASE1ST_EXPIRED;
32020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check if we have another, still valid, phase1 SA. */
3204c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	new_iph1 = getph1byaddr(iph1->local, iph1->remote, 1);
32050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
32070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
32080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Keep all others phase2 SAs.
32090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
32100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
32110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL) {
32120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
32130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pfkey_dump_sadb returned nothing.\n");
32140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
32150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)buf->v;
32180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	end = (struct sadb_msg *)(buf->v + buf->l);
32190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (msg < end) {
32210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
32220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
32230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
32240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg->sadb_msg_type != SADB_DUMP) {
32250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
32300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfkey_check (%s)\n", ipsec_strerror());
32320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
32370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!sa ||
32380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    !mhp[SADB_EXT_ADDRESS_SRC] ||
32390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    !mhp[SADB_EXT_ADDRESS_DST]) {
32400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
32440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
32450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->sadb_sa_state != SADB_SASTATE_LARVAL &&
32470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    sa->sadb_sa_state != SADB_SASTATE_MATURE &&
32480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    sa->sadb_sa_state != SADB_SASTATE_DYING) {
32490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
32540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * check in/outbound SAs.
32550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Select only SAs where src == local and dst == remote (outgoing)
32560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * or src == remote and dst == local (incoming).
32570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
3258c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) &&
3259c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			(CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) {
32600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
32650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
32660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Check if there is another valid ISAKMP-SA */
32680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new_iph1 != NULL) {
32690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2 == NULL) {
32710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* No handler... still send a pfkey_delete message, but log this !*/
32720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_INFO, LOCATION, NULL,
32730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"Unknown IPsec-SA spi=%u, hmmmm?\n",
32740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					ntohl(sa->sadb_sa_spi));
32750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}else{
32760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3277c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				/*
32780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 * If we have a new ph1, do not purge IPsec-SAs binded
32790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 *  to a different ISAKMP-SA
32800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 */
32810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (iph2->ph1 != NULL && iph2->ph1 != iph1){
32820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					msg = next;
32830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					continue;
32840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
32850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* If the ph2handle is established, do not purge IPsec-SA */
32870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (iph2->status == PHASE2ST_ESTABLISHED ||
32880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					iph2->status == PHASE2ST_EXPIRED) {
3289c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
32900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_INFO, LOCATION, NULL,
32910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n",
32920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 ntohl(sa->sadb_sa_spi),
32930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 isakmp_pindex(&(new_iph1->index), new_iph1->msgid));
32940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					msg = next;
32950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					continue;
32960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
32970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
32980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3300c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
33010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pfkey_send_delete(lcconf->sock_pfkey,
33020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				  msg->sadb_msg_satype,
33030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				  IPSEC_MODE_ANY,
33040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				  src, dst, sa->sadb_sa_spi);
33050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* delete a relative phase 2 handle. */
33070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2 != NULL) {
33080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delete_spd(iph2, 0);
3309c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			unbindph12(iph2);
33100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
33110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
33120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
33130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
33150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "purged IPsec-SA spi=%u.\n",
33160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 ntohl(sa->sadb_sa_spi));
33170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msg = next;
33190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
33200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
33220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
33230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Mark the phase1 handler as EXPIRED */
33250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
33260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "purged ISAKMP-SA spi=%s.\n",
33270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 isakmp_pindex(&(iph1->index), iph1->msgid));
33280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3329c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph1->sce);
3330c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3331c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
33320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3334c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid
33350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdelete_spd(iph2, created)
33360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
33370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 	u_int64_t created;
33380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
33400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage addr;
33410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t pref;
33420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src;
33430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *dst;
33440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
33450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */
33460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL)
33480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
33490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Delete the SPD entry if we generated it
33510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
33520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (! iph2->generated_spidx )
33530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
33540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = iph2->src;
33560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = iph2->dst;
33570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
3359c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 "generated policy, deleting it.\n");
3360c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
33610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&spidx, 0, sizeof(spidx));
33620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->spidx_gen = (caddr_t )&spidx;
3363c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
33640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make inbound policy */
33650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->src = dst;
33660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->dst = src;
33670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dir = IPSEC_DIR_INBOUND;
33680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.ul_proto = 0;
3369c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3370c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
33710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Note: code from get_proposal_r
33720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
3373c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
33740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
3375c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
33760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
33770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * make destination address in spidx from either ID payload
33780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * or phase 1 address into a address in spidx.
33790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
33800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id != NULL
33810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&& (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
33820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
33830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
33840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
33850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get a destination address of a policy */
33860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = ipsecdoi_id2sockaddr(iph2->id,
33870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang									 (struct sockaddr *)&spidx.dst,
33880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang									 &spidx.prefd, &spidx.ul_proto);
33890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error)
33900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto purge;
3391c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
33920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
33930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
33940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * get scopeid from the SA address.
33950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * note that the phase 1 source address is used as
3396c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * a destination address to search for a inbound
33970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * policy entry because rcoon is responder.
33980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
33990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
3400c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if ((error =
34010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 setscopeid((struct sockaddr *)&spidx.dst,
34020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							iph2->src)) != 0)
34030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3406c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
34070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
34080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
34090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			idi2type = _XIDT(iph2->id);
3410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
34110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
3412c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
34130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "get a destination address of SP index "
34150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "from phase1 address "
34160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "due to no ID payloads found "
34170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "OR because ID type is not address.\n");
3418c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
34190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
3420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * copy the SOURCE address of IKE into the
3421c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * DESTINATION address of the key to search the
34220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * SPD because the direction of policy is inbound.
34230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
34240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
34250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (spidx.dst.ss_family) {
34260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
3427c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			spidx.prefd =
34280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in_addr) << 3;
34290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
3432c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			spidx.prefd =
34330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in6_addr) << 3;
34340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
34370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefd = 0;
34380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3441c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3442c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* make source address in spidx */
34430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id_p != NULL
34440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&& (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
34450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
34460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
34470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
34480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get a source address of inbound SA */
34490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = ipsecdoi_id2sockaddr(iph2->id_p,
3450c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh									 (struct sockaddr *)&spidx.src,
3451c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh									 &spidx.prefs, &spidx.ul_proto);
34520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error)
34530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto purge;
34540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
34570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * get scopeid from the SA address.
34580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * for more detail, see above of this function.
34590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
34600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
3461c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			error =
34620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				setscopeid((struct sockaddr *)&spidx.src,
34630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						   iph2->dst);
34640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (error)
34650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3469c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* make id[src,dst] if both ID types are IP address and same */
34700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id_p) == idi2type
34710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&& spidx.dst.ss_family == spidx.src.ss_family) {
3472c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			iph2->src_id =
34730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				dupsaddr((struct sockaddr *)&spidx.dst);
3474c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (iph2->src_id == NULL) {
34750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
34760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					 "allocation failed\n");
34770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3479c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			iph2->dst_id =
34800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				dupsaddr((struct sockaddr *)&spidx.src);
3481c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (iph2->dst_id == NULL) {
34820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
34830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					 "allocation failed\n");
34840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
34860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
34890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "get a source address of SP index "
34910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "from phase1 address "
34920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "due to no ID payloads found "
34930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "OR because ID type is not address.\n");
34940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* see above comment. */
34960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
34970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (spidx.src.ss_family) {
34980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
3499c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			spidx.prefs =
35000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in_addr) << 3;
35010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
35030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
3504c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			spidx.prefs =
35050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in6_addr) << 3;
35060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
35080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
35090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefs = 0;
35100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef _XIDT
35150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
35170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "get a src address from ID payload "
35180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "%s prefixlen=%u ul_proto=%u\n",
35190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 saddr2str((struct sockaddr *)&spidx.src),
35200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 spidx.prefs, spidx.ul_proto);
35210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
35220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "get dst address from ID payload "
35230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "%s prefixlen=%u ul_proto=%u\n",
35240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 saddr2str((struct sockaddr *)&spidx.dst),
35250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 spidx.prefd, spidx.ul_proto);
35260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
35280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * convert the ul_proto if it is 0
35290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because 0 in ID payload means a wild card.
35300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
35310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spidx.ul_proto == 0)
35320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.ul_proto = IPSEC_ULPROTO_ANY;
35330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef _XIDT
35350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check if the generated SPD has the same timestamp as the SA.
35370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * If timestamps are different, this means that the SPD entry has been
35380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * refreshed by another SA, and should NOT be deleted with the current SA.
35390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
35400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if( created ){
35410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct secpolicy *p;
3542c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
35430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = getsp(&spidx);
35440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(p != NULL){
35450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* just do no test if p is NULL, because this probably just means
35460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * that the policy has already be deleted for some reason.
35470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
35480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if(p->spidx.created != created)
35490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
35500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* End of code from get_proposal_r
35540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
35550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pk_sendspddelete(iph2) < 0) {
35570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
35580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(inbound) failed.\n");
35590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}else{
35600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
35610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(inbound) sent.\n");
35620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_POLICY_FWD
35650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make forward policy if required */
35660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tunnel_mode_prop(iph2->approval)) {
35670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.dir = IPSEC_DIR_FWD;
35680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pk_sendspddelete(iph2) < 0) {
35690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
35700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "pfkey spddelete(forward) failed.\n");
35710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}else{
35720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
35730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "pfkey spddelete(forward) sent.\n");
35740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
35770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make outbound policy */
35790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->src = src;
35800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->dst = dst;
35810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dir = IPSEC_DIR_OUTBOUND;
35820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr = spidx.src;
35830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.src = spidx.dst;
35840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dst = addr;
35850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pref = spidx.prefs;
35860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefs = spidx.prefd;
35870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefd = pref;
35880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pk_sendspddelete(iph2) < 0) {
35900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
35910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(outbound) failed.\n");
35920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}else{
35930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
35940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(outbound) sent.\n");
35950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpurge:
35970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->spidx_gen=NULL;
35980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
35990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
36020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
36030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetscopeid(sp_addr0, sa_addr0)
36040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *sp_addr0, *sa_addr0;
36050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
36060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in6 *sp_addr, *sa_addr;
3607c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
36080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_addr = (struct sockaddr_in6 *)sp_addr0;
36090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_addr = (struct sockaddr_in6 *)sa_addr0;
36100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr)
36120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr)
36130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr))
36140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
36150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* this check should not be here ? */
36170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa_addr->sin6_family != AF_INET6) {
36180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
36190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"can't get scope ID: family mismatch\n");
36200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
36210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
36240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
36250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"scope ID is not supported except of lladdr.\n");
36260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
36270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_addr->sin6_scope_id = sa_addr->sin6_scope_id;
36300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
36320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
36330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3634