isakmp.c revision 1c71527b277e2dc256262da2ed2169c566c5bf4d
11c71527b277e2dc256262da2ed2169c566c5bf4dChia-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.
80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/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
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif /* __linux__ */
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if defined(__NetBSD__) || defined(__FreeBSD__) ||	\
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  (defined(__APPLE__) && defined(__MACH__))
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/in.h>
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/udp.h>
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/in_systm.h>
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/ip.h>
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  define SOL_UDP IPPROTO_UDP
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif /* __NetBSD__ / __FreeBSD__ */
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nostate1 __P((struct ph1handle *, vchar_t *));
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nostate2 __P((struct ph2handle *, vchar_t *));
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangextern caddr_t val2str(const char *, size_t);
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*ph1exchange[][2][PHASE1ST_MAX])
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	__P((struct ph1handle *, vchar_t *)) = {
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* error */
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { {}, {}, },
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Identity Protection exchange */
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send,
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, },
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send,
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, },
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Aggressive exchange */
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send,
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    nostate1, nostate1, nostate1, nostate1, nostate1, },
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send,
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    nostate1, nostate1, nostate1, nostate1, nostate1, },
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Base exchange */
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, base_i1send, nostate1, base_i2recv, base_i2send,
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    base_i3recv, base_i3send, nostate1, nostate1, nostate1, },
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send,
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    nostate1, nostate1, nostate1, nostate1, nostate1, },
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*ph2exchange[][2][PHASE2ST_MAX])
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	__P((struct ph2handle *, vchar_t *)) = {
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* error */
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang { {}, {}, },
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Quick mode for IKE */
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send,
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, },
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate2, quick_r1recv, quick_r1prep, nostate2, quick_r2send,
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, }
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *));
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int ph1_main __P((struct ph1handle *, vchar_t *));
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int quick_main __P((struct ph2handle *, vchar_t *));
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_ph1begin_r __P((vchar_t *,
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *, struct sockaddr *, u_int8_t));
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_ph2begin_i __P((struct ph1handle *, struct ph2handle *));
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *));
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int etypesw1 __P((int));
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int etypesw2 __P((int));
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int frag_handler(struct ph1handle *,
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    vchar_t *, struct sockaddr *, struct sockaddr *);
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * isakmp packet handler
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_handler(so_isakmp)
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so_isakmp;
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp isakmp;
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	union {
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char		buf[sizeof (isakmp) + 4];
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int32_t	non_esp[2];
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char		lbuf[sizeof(struct udphdr) +
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     sizeof(struct iphdr) +
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     sizeof(struct ip) +
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     sizeof(isakmp) + 4];
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} x;
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage remote;
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage local;
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int remote_len = sizeof(remote);
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int local_len = sizeof(local);
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0, extralen = 0;
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL, *tmpbuf = NULL;
2151c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	int error = -1, res;
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read message by MSG_PEEK */
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recvfromto(so_isakmp, x.buf, sizeof(x),
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    MSG_PEEK, (struct sockaddr *)&remote, &remote_len,
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (struct sockaddr *)&local, &local_len)) < 0) {
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to receive isakmp packet: %s\n",
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror (errno));
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* keep-alive packet - ignore */
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 1 && (x.buf[0]&0xff) == 0xff) {
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Pull the keep-alive packet */
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)x.buf, 1,
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    0, (struct sockaddr *)&remote, &remote_len)) != 1) {
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "failed to receive keep alive packet: %s\n",
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror (errno));
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Lucent IKE in UDP encapsulation */
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct udphdr *udp;
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct iphdr *ip;
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		udp = (struct udphdr *)&x.lbuf[0];
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ntohs(udp->dest) == 501) {
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ip = (struct iphdr *)(x.lbuf + sizeof(*udp));
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			extralen += sizeof(*udp) + ip->ihl;
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ip *ip;
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		udp = (struct udphdr *)&x.lbuf[0];
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ntohs(udp->uh_dport) == 501) {
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ip = (struct ip *)(x.lbuf + sizeof(*udp));
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			extralen += sizeof(*udp) + ip->ip_hl;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* we don't know about portchange yet,
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   look for non-esp marker instead */
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x.non_esp[0] == 0 && x.non_esp[1] != 0)
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		extralen = NON_ESP_MARKER_LEN;
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* now we know if there is an extra non-esp
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   marker at the beginning or not */
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp));
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check isakmp header length, as well as sanity of header length */
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) {
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"packet shorter than isakmp header size (%u, %u, %zu)\n",
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len, ntohl(isakmp.len), sizeof(isakmp));
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* dummy receive */
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to receive isakmp packet: %s\n",
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror (errno));
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* reject it if the size is tooooo big. */
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ntohl(isakmp.len) > 0xffff) {
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"the length in the isakmp header is too big.\n");
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to receive isakmp packet: %s\n",
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror (errno));
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read real message */
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) {
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate reading buffer (%u Bytes)\n",
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ntohl(isakmp.len) + extralen);
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* dummy receive */
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to receive isakmp packet: %s\n",
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror (errno));
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recvfromto(so_isakmp, (char *)tmpbuf->v, tmpbuf->l,
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                    0, (struct sockaddr *)&remote, &remote_len,
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                    (struct sockaddr *)&local, &local_len)) < 0) {
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to receive isakmp packet: %s\n",
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror (errno));
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((buf = vmalloc(len - extralen)) == NULL) {
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate reading buffer (%u Bytes)\n",
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(len - extralen));
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy (buf->v, tmpbuf->v + extralen, buf->l);
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len -= extralen;
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != buf->l) {
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"received invalid length (%d != %zu), why ?\n",
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len, buf->l);
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"%d bytes message received %s\n",
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len, saddr2str_fromto("from %s to %s",
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&remote,
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&local));
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plogdump(LLV_DEBUG, buf->v, buf->l);
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* avoid packets with malicious port/address */
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port((struct sockaddr *)&remote) == 0) {
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"src port == 0 (valid as UDP but not with IKE)\n");
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX: check sender whether to be allowed or not to accept */
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX: I don't know how to check isakmp half connection attack. */
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* simply reply if the packet was processed. */
3661c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	res=check_recvdpkt((struct sockaddr *)&remote,(struct sockaddr *)&local, buf);
3671c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	if (res) {
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_NOTIFY, LOCATION, NULL,
3691c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			"the packet is retransmitted by %s (%d).\n",
3701c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			 saddr2str((struct sockaddr *)&remote), res);
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = 0;
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* isakmp main routine */
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_main(buf, (struct sockaddr *)&remote,
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&local) != 0) goto end;
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tmpbuf != NULL)
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(tmpbuf);
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main processing to handle isakmp payload
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_main(msg, remote, local)
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_index *index = (isakmp_index *)isakmp;
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t msgid = isakmp->msgid;
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_printpacket(msg, remote, local, 0);
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the initiator's cookie must not be zero */
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) {
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"malformed cookie received.\n");
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check the Major and Minor Version fields. */
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * XXX Is is right to check version here ?
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * I think it may no be here because the version depends
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * on exchange status.
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp->v < ISAKMP_VERSION_NUMBER) {
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ISAKMP_GETMAJORV(isakmp->v) < ISAKMP_MAJOR_VERSION) {
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid major version %d.\n",
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_GETMAJORV(isakmp->v));
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if ISAKMP_MINOR_VERSION > 0
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) {
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid minor version %d.\n",
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_GETMINORV(isakmp->v));
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check the Flags field. */
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX How is the exclusive check, E and A ? */
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) {
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid flag 0x%02x.\n", isakmp->flags);
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore commit bit. */
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) {
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->msgid == 0) {
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_nx(isakmp, remote, local,
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_NTYPE_INVALID_FLAGS, NULL);
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Commit bit on phase1 forbidden.\n");
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = getph1byindex(index);
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 != NULL) {
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    iph1->side == INITIATOR) {
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, remote,
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"malformed cookie received or "
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"the initiator's cookies collide.\n");
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Floating ports for NAT-T */
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (NATT_AVAILABLE(iph1) &&
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    ! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    ((cmpsaddrstrict(iph1->remote, remote) != 0) ||
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (cmpsaddrstrict(iph1->local, local) != 0)))
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* prevent memory leak */
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(iph1->remote);
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(iph1->local);
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->remote = NULL;
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->local = NULL;
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* copy-in new addresses */
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->remote = dupsaddr(remote);
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->remote == NULL) {
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang           			plog(LLV_ERROR, LOCATION, iph1->remote,
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "phase1 failed: dupsaddr failed.\n");
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				remph1(iph1);
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				delph1(iph1);
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->local = dupsaddr(local);
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->local == NULL) {
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang           			plog(LLV_ERROR, LOCATION, iph1->remote,
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "phase1 failed: dupsaddr failed.\n");
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				remph1(iph1);
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				delph1(iph1);
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* set the flag to prevent further port floating
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			   (FIXME: should we allow it? E.g. when the NAT gw
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    is rebooted?) */
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* print some neat info */
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog (LLV_INFO, LOCATION, NULL,
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			      "NAT-T: ports changed to: %s\n",
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			      saddr2str_fromto ("%s<->%s", iph1->remote, iph1->local));
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			natt_keepalive_add_ph1 (iph1);
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* must be same addresses in one stream of a phase at least. */
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (cmpsaddrstrict(iph1->remote, remote) != 0) {
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char *saddr_db, *saddr_act;
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr_db = racoon_strdup(saddr2str(iph1->remote));
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr_act = racoon_strdup(saddr2str(remote));
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			STRDUP_FATAL(saddr_db);
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			STRDUP_FATAL(saddr_act);
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, remote,
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"remote address mismatched. db=%s, act=%s\n",
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				saddr_db, saddr_act);
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(saddr_db);
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(saddr_act);
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * don't check of exchange type here because other type will be
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with same index, for example, informational exchange.
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX more acceptable check */
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (isakmp->etype) {
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_IDENT:
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_AGG:
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_BASE:
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* phase 1 validity check */
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->msgid != 0) {
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"message id should be zero in phase1.\n");
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* search for isakmp status record of phase 1 */
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * the packet must be the 1st message from a initiator
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * or the 2nd message from the responder.
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* search for phase1 handle by index without r_ck */
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1 = getph1byindex0(index);
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1 == NULL) {
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*it must be the 1st message from a initiator.*/
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (memcmp(&isakmp->r_ck, r_ck0,
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sizeof(cookie_t)) != 0) {
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_DEBUG, LOCATION, remote,
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"malformed cookie received "
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"or the spi expired.\n");
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* it must be responder's 1st exchange. */
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (isakmp_ph1begin_r(msg, remote, local,
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					isakmp->etype) < 0)
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*NOTREACHED*/
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* it must be the 2nd message from the responder. */
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->side != INITIATOR) {
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, remote,
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"malformed cookie received. "
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"it has to be as the initiator.  %s\n",
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					isakmp_pindex(&iph1->index, 0));
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Don't delete phase 1 handler when the exchange type
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * in handler is not equal to packet's one because of no
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * authencication completed.
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->etype != isakmp->etype) {
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph1->remote,
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"exchange type is mismatched: "
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"db=%s packet=%s, ignore it.\n",
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_isakmp_etype(iph1->etype),
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_isakmp_etype(isakmp->etype));
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* call main process of phase 1 */
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ph1_main(iph1, msg) < 0) {
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph1->remote,
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"phase1 negotiation failed.\n");
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph1(iph1);
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph1(iph1);
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_AUTH:
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, remote,
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unsupported exchange %d received.\n",
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp->etype);
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_INFO:
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_ACKINFO:
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * iph1 must be present for Information message.
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * if iph1 is null then trying to get the phase1 status
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * as the packet from responder againt initiator's 1st
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * exchange in phase 1.
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * NOTE: We think such informational exchange should be ignored.
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1 = getph1byindex0(index);
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1 == NULL) {
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, remote,
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"unknown Informational "
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"exchange received.\n");
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (cmpsaddrstrict(iph1->remote, remote) != 0) {
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_WARNING, LOCATION, remote,
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"remote address mismatched. "
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"db=%s\n",
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					saddr2str(iph1->remote));
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_info_recv(iph1, msg) < 0)
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_QUICK:
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ph2handle *iph2;
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_nx(isakmp, remote, local,
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_NTYPE_INVALID_COOKIE, NULL);
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"can't start the quick mode, "
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"there is no ISAKMP-SA, %s\n",
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex((isakmp_index *)&isakmp->i_ck,
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					isakmp->msgid));
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Reinit the IVM if it's still there */
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			oakley_delivm(iph1->mode_cfg->ivm);
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->mode_cfg->ivm = NULL;
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check status of phase 1 whether negotiated or not. */
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->status != PHASE1ST_ESTABLISHED) {
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"can't start the quick mode, "
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"there is no valid ISAKMP-SA, %s\n",
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph1->index, iph1->msgid));
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* search isakmp phase 2 stauts record. */
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2 = getph2bymsgid(iph1, msgid);
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2 == NULL) {
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* it must be new negotiation as responder */
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (isakmp_ph2begin_r(iph1, msg) < 0)
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*NOTREACHED*/
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* commit bit. */
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we keep to set commit bit during negotiation.
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * When SA is configured, bit will be reset.
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * don't initiate commit bit.  should be fixed in the future.
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->flags |= ISAKMP_FLAG_C;
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* call main process of quick mode */
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (quick_main(iph2, msg) < 0) {
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph1->remote,
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"phase2 negotiation failed.\n");
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			unbindph12(iph2);
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_NEWGRP:
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Unknown new group mode exchange, "
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"there is no ISAKMP-SA.\n");
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_newgroup_r(iph1, msg);
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_CFG:
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "mode config %d from %s, "
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "but we have no ISAKMP-SA.\n",
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     isakmp->etype, saddr2str(remote));
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_cfg_r(iph1, msg);
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_NONE:
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid exchange type %d from %s.\n",
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp->etype, saddr2str(remote));
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main function of phase 1.
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangph1_main(iph1, msg)
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore a packet */
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->status == PHASE1ST_ESTABLISHED)
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* receive */
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ph1exchange[etypesw1(iph1->etype)]
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph1->side]
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph1->status] == NULL) {
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph1->remote,
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"why isn't the function defined.\n");
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = (ph1exchange[etypesw1(iph1->etype)]
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph1->side]
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph1->status])(iph1, msg);
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
8011c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * When an invalid packet is received on phase1, it should
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * be selected to process this packet.  That is to respond
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with a notify and delete phase 1 handler, OR not to respond
8061c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * and keep phase 1 handler. However, in PHASE1ST_START when
8071c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * acting as RESPONDER we must not keep phase 1 handler or else
8081c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * it will stay forever.
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
8101c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
8111c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
8121c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			plog(LLV_ERROR, LOCATION, iph1->remote,
8131c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				"failed to pre-process packet.\n");
8141c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			return -1;
8151c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		} else {
8161c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			/* ignore the error and keep phase 1 handler */
8171c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			return 0;
8181c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		}
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef ENABLE_FRAG
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* free resend buffer */
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->sendbuf == NULL) {
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no buffer found as sendbuf\n");
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	VPTRINIT(iph1->sendbuf);
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off schedule */
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph1->scr);
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send */
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph1exchange[etypesw1(iph1->etype)]
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->side]
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->status])(iph1, msg) != 0) {
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph1->remote,
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to process packet.\n");
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status),
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->status == PHASE1ST_ESTABLISHED) {
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gettimeofday(&iph1->end, NULL);
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		syslog(LOG_NOTICE, "%s(%s): %8.6f",
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase1", s_isakmp_etype(iph1->etype),
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			timedelta(&iph1->start, &iph1->end));
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* save created date. */
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)time(&iph1->created);
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* add to the schedule to expire, and seve back pointer. */
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->sce = sched_new(iph1->approval->lifetime,
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    isakmp_ph1expire_stub, iph1);
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch(AUTHMETHOD(iph1)) {
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				xauth_sendreq(iph1);
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* XXX Don't process INITIAL_CONTACT */
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph1->rmconf->ini_contact = 0;
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_DPD
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Schedule the r_u_there.... */
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(iph1->dpd_support && iph1->rmconf->dpd_interval)
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_sched_r_u(iph1, 0);
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* INITIAL-CONTACT processing */
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't anything if local test mode. */
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!f_local
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* send INITIAL-CONTACT */
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_n1(iph1,
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* insert a node into contacted list. */
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (inscontacted(iph1->remote) == -1) {
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, iph1->remote,
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to add contacted list.\n");
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* ignore */
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		log_ph1established(iph1);
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "===\n");
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * SA up shell script hook: do it now,except if
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * ISAKMP mode config was requested. In the later
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * case it is done when we receive the configuration.
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((iph1->status == PHASE1ST_ESTABLISHED) &&
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    !iph1->rmconf->mode_cfg) {
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (AUTHMETHOD(iph1)) {
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Unimplemeted... */
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				script_hook(iph1, SCRIPT_PHASE1_UP);
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main function of quick mode.
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_main(iph2, msg)
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore a packet */
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status == PHASE2ST_ESTABLISHED
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || iph2->status == PHASE2ST_GETSPISENT)
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* receive */
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ph2exchange[etypesw2(isakmp->etype)]
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph2->side]
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph2->status] == NULL) {
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"why isn't the function defined.\n");
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = (ph2exchange[etypesw2(isakmp->etype)]
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph2->side]
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph2->status])(iph2, msg);
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to pre-process packet.\n");
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error == ISAKMP_INTERNAL_ERROR)
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_info_send_n1(iph2->ph1, error, NULL);
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* when using commit bit, status will be reached here. */
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status == PHASE2ST_ADDSA)
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* free resend buffer */
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sendbuf == NULL) {
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no buffer found as sendbuf\n");
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	VPTRINIT(iph2->sendbuf);
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off schedule */
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->scr);
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send */
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(isakmp->etype)]
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->side]
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->status])(iph2, msg) != 0) {
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to process packet.\n");
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2",
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 1 for initiator */
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1begin_i(rmconf, remote, local)
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get new entry to isakmp status table. */
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = newph1();
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL)
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->status = PHASE1ST_START;
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->rmconf = rmconf;
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->side = INITIATOR;
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->version = ISAKMP_VERSION_NUMBER;
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->msgid = 0;
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->flags = 0;
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->ph2cnt = 0;
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->gssapi_state = NULL;
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(rmconf->ike_frag == ISAKMP_FRAG_FORCE)
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->frag = 1;
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->frag = 0;
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->frag_chain = NULL;
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->approval = NULL;
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX copy remote address */
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)insph1(iph1);
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start phase 1 exchange */
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->etype = rmconf->etypes->type;
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph1->local));
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"initiate new phase 1 negotiation: %s<=>%s\n",
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph1->remote));
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"begin %s mode.\n",
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_etype(iph1->etype));
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph1->start, NULL);
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start exchange */
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph1exchange[etypesw1(iph1->etype)]
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->side]
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->status])(iph1, NULL) != 0) {
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* failed to start phase 1 negotiation */
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase1",
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(iph1->etype, iph1->side, iph1->status),
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 1 for responder */
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1begin_r(msg, remote, local, etype)
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t etype;
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct etypes *etypeok;
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* look for my configuration */
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rmconf = getrmconf(remote);
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rmconf == NULL) {
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"couldn't find "
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"configuration.\n");
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check to be acceptable exchange type */
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	etypeok = check_etypeok(rmconf, etype);
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (etypeok == NULL) {
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"not acceptable %s mode\n", s_isakmp_etype(etype));
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get new entry to isakmp status table. */
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = newph1();
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL)
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->status = PHASE1ST_START;
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->rmconf = rmconf;
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->flags = 0;
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->side = RESPONDER;
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->etype = etypeok->type;
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->version = isakmp->v;
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->msgid = 0;
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->gssapi_state = NULL;
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->frag = 0;
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->frag_chain = NULL;
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->approval = NULL;
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* RFC3947 says that we MUST accept new phases1 on NAT-T floated port.
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * We have to setup this flag now to correctly generate the first reply.
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Don't know if a better check could be done for that ?
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(extract_port(local) == lcconf->port_isakmp_natt)
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->natt_flags |= (NAT_PORTS_CHANGED);
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy remote address */
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)insph1(iph1);
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph1->local));
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"respond new phase 1 negotiation: %s<=>%s\n",
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph1->remote));
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"begin %s mode.\n", s_isakmp_etype(etype));
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph1->start, NULL);
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef ENABLE_FRAG
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start exchange */
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph1exchange[etypesw1(iph1->etype)]
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph1->side]
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph1->status])(iph1, msg) < 0
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || (ph1exchange[etypesw1(iph1->etype)]
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->side]
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->status])(iph1, msg) < 0) {
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to process packet.\n");
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase1",
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(iph1->etype, iph1->side, iph1->status),
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else /* ENABLE_FRAG */
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* now that we have a phase1 handle, feed back into our
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * main receive function to catch fragmented packets
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return isakmp_main(msg, remote, local);
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* ENABLE_FRAG */
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 2 for initiator */
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2begin_i(iph1, iph2)
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_check(iph1) != 0) {
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Attempt to start phase 2 whereas Xauth failed\n");
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found ISAKMP-SA. */
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph2->src));
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"initiate new phase 2 negotiation: %s<=>%s\n",
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph2->dst));
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph2->start, NULL);
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found isakmp-sa */
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bindph12(iph1, iph2);
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_STATUS2;
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 [iph2->side]
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 [iph2->status])(iph2, NULL) < 0) {
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2);
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* release ipsecsa handler due to internal error. */
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 2 for responder */
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2begin_r(iph1, msg)
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2 = 0;
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_check(iph1) != 0) {
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Attempt to start phase 2 whereas Xauth failed\n");
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = newph2();
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate phase2 entry.\n");
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->ph1 = iph1;
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->side = RESPONDER;
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_START;
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->flags = isakmp->flags;
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->msgid = isakmp->msgid;
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->seq = pk_getseq();
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->ivm == NULL) {
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->dst = dupsaddr(iph1->remote);	/* XXX should be considered */
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->dst == NULL) {
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->src = dupsaddr(iph1->local);	/* XXX should be considered */
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->src == NULL) {
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (set_port(iph2->dst, 0) == NULL ||
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    set_port(iph2->src, 0) == NULL) {
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "invalid family: %d\n", iph2->dst->sa_family);
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* add new entry to isakmp status table */
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	insph2(iph2);
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bindph12(iph1, iph2);
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph2->src));
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"respond new phase 2 negotiation: %s<=>%s\n",
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph2->dst));
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                   [iph2->side]
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                   [iph2->status])(iph2, msg);
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph1->remote,
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to pre-process packet.\n");
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error != ISAKMP_INTERNAL_ERROR)
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_n1(iph2->ph1, error, NULL);
13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * release handler because it's wrong that ph2handle is kept
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * after failed to check message for responder's.
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2);
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send */
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(isakmp->etype)]
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->side]
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->status])(iph2, msg) < 0) {
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to process packet.\n");
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't release handler */
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2",
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * parse ISAKMP payloads, without ISAKMP base header.
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_parsewoh(np0, gen, len)
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int np0;
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char np = np0 & 0xff;
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen, plen;
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *result;
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_parse_t *p, *ep;
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * 5 is a magic number, but any value larger than 2 should be fine
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * as we do vrealloc() in the following loop.
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	result = vmalloc(sizeof(struct isakmp_parse_t) * 5);
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (result == NULL) {
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer.\n");
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = (struct isakmp_parse_t *)result->v;
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ep = (struct isakmp_parse_t *)(result->v + result->l - sizeof(*ep));
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = len;
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* parse through general headers */
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (0 < tlen && np != ISAKMP_NPTYPE_NONE) {
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tlen <= sizeof(struct isakmp_gen)) {
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* don't send information, see isakmp_ident_r1() */
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid length of payload\n");
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(result);
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seen nptype=%u(%s)\n", np, s_isakmp_nptype(np));
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->type = np;
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->len = ntohs(gen->len);
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) {
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid length of payload\n");
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(result);
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->ptr = gen;
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p++;
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ep <= p) {
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int off;
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			off = p - (struct isakmp_parse_t *)result->v;
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = vrealloc(result, result->l * 2);
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (result == NULL) {
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to realloc buffer.\n");
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(result);
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return NULL;
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ep = (struct isakmp_parse_t *)
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(result->v + result->l - sizeof(*ep));
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = (struct isakmp_parse_t *)result->v;
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += off;
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		np = gen->np;
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = ntohs(gen->len);
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gen = (struct isakmp_gen *)((caddr_t)gen + plen);
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen -= plen;
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->type = ISAKMP_NPTYPE_NONE;
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->len = 0;
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->ptr = NULL;
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "succeed.\n");
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return result;
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * parse ISAKMP payloads, including ISAKMP base header.
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_parse(buf)
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)buf->v;
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *result;
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char np;
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	np = isakmp->np;
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen = (struct isakmp_gen *)(buf->v + sizeof(*isakmp));
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = buf->l - sizeof(struct isakmp);
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	result = isakmp_parsewoh(np, gen, tlen);
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return result;
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%% */
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_init()
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize a isakmp status table */
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initph1tree();
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initph2tree();
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initctdtree();
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	init_recvdpkt();
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_open() < 0)
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(0);
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_close();
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(-1);
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make strings containing i_cookie + r_cookie + msgid
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char *
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_pindex(index, msgid)
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const isakmp_index *index;
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_int32_t msgid;
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char buf[64];
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_char *p;
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i, j;
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(buf, 0, sizeof(buf));
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy index */
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = (const u_char *)index;
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		j += 2;
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (i) {
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 7:
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf[j++] = ':';
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msgid == 0)
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return buf;
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy msgid */
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	snprintf((char *)&buf[j], sizeof(buf) - j, ":%08x", ntohs(msgid));
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* open ISAKMP sockets. */
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_open()
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int yes = 1;
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ifnum = 0, encap_ifnum = 0;
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pktinfo;
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct myaddrs *p;
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = lcconf->myaddrs; p; p = p->next) {
15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!p->addr)
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* warn if wildcard address - should we forbid this? */
15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (p->addr->sa_family) {
15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (((struct sockaddr_in *)p->addr)->sin_addr.s_addr == 0)
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_WARNING, LOCATION, NULL,
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"listening to wildcard address,"
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"broadcast IKE packet may kill you\n");
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)p->addr)->sin6_addr))
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_WARNING, LOCATION, NULL,
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"listening to wildcard address, "
15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"broadcast IKE packet may kill you\n");
15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported address family %d\n",
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				lcconf->default_af);
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err_and_next;
16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->addr->sa_family == AF_INET6 &&
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    p->addr)->sin6_addr))
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Ignoring multicast address %s\n",
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				saddr2str(p->addr));
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(p->addr);
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p->addr = NULL;
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((p->sock = socket(p->addr->sa_family, SOCK_DGRAM, 0)) < 0) {
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"socket (%s)\n", strerror(errno));
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err_and_next;
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to put socket in non-blocking mode\n");
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* receive my interface address on inbound packets. */
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (p->addr->sa_family) {
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (setsockopt(p->sock, IPPROTO_IP,
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				       IP_PKTINFO,
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				       IP_RECVDSTADDR,
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(const void *)&yes, sizeof(yes)) < 0) {
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"setsockopt IP_RECVDSTADDR (%s)\n",
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					strerror(errno));
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err_and_next;
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6_ADVAPI
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef IPV6_RECVPKTINFO
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pktinfo = IPV6_RECVPKTINFO;
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else  /* old adv. API */
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pktinfo = IPV6_PKTINFO;
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* IPV6_RECVPKTINFO */
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pktinfo = IPV6_RECVDSTADDR;
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (setsockopt(p->sock, IPPROTO_IPV6, pktinfo,
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(const void *)&yes, sizeof(yes)) < 0)
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"setsockopt IPV6_RECVDSTADDR (%d):%s\n",
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					pktinfo, strerror(errno));
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err_and_next;
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef IPV6_USE_MIN_MTU
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->addr->sa_family == AF_INET6 &&
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (void *)&yes, sizeof(yes)) < 0) {
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "setsockopt IPV6_USE_MIN_MTU (%s)\n",
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror(errno));
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (setsockopt_bypass(p->sock, p->addr->sa_family) < 0)
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err_and_next;
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (bind(p->sock, p->addr, sysdep_sa_len(p->addr)) < 0) {
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, p->addr,
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to bind to address %s (%s).\n",
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				saddr2str(p->addr), strerror(errno));
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			close(p->sock);
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err_and_next;
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ifnum++;
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s used as isakmp port (fd=%d)\n",
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr2str(p->addr), p->sock);
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->addr->sa_family == AF_INET) {
17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int option = -1;
17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if(p->udp_encap)
17050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				option = UDP_ENCAP_ESPINUDP;
17060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01)
17070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				option = UDP_ENCAP_ESPINUDP_NON_IKE;
17090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if(option != -1){
17110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (setsockopt (p->sock, SOL_UDP,
17120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    UDP_ENCAP, &option, sizeof (option)) < 0) {
17130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_WARNING, LOCATION, NULL,
17140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "setsockopt(%s): UDP_ENCAP %s\n",
17150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
17160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 strerror(errno));
17170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto skip_encap;
17180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
17190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else {
17200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_INFO, LOCATION, NULL,
17210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 "%s used for NAT-T\n",
17220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 saddr2str(p->addr));
17230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					encap_ifnum++;
17240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
17250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
17260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangskip_encap:
17280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		continue;
17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	err_and_next:
17320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p->addr);
17330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->addr = NULL;
17340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (! lcconf->autograbaddr && lcconf->strict_address)
17350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
17360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		continue;
17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ifnum) {
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no address could be bound.\n");
17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (natt_enabled_in_rmconf() && !encap_ifnum) {
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"NAT-T is enabled in at least one remote{} section,\n");
17490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
17500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"but no 'isakmp_natt' address was specified!\n");
17510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_close()
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct myaddrs *p, *next;
17610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = lcconf->myaddrs; p; p = next) {
17630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		next = p->next;
17640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!p->addr) {
17660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(p);
17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
17680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		close(p->sock);
17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p->addr);
17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p);
17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lcconf->myaddrs = NULL;
17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_send(iph1, sbuf)
17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sbuf;
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int s;
17841c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	vchar_t *vbuf = NULL, swap;
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0;
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17891c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	/* Check if NON_ESP_MARKER_LEN is already there (happens when resending packets)
17901c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	 */
17911c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	if(extralen == NON_ESP_MARKER_LEN &&
17921c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	   *(u_int32_t *)sbuf->v == 0)
17931c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		extralen = 0;
17941c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Do not add the non ESP marker for a packet that will
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * be fragmented. The non ESP marker should appear in
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * all fragment's packets, but not in the fragmented packet
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN)
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		extralen = 0;
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extralen)
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
18060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   must added just before the packet itself. For this we must
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   allocate a new buffer and release it at the end. */
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extralen) {
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) {
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "vbuf allocation failed\n");
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*(u_int32_t *)vbuf->v = 0;
18170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy (vbuf->v + extralen, sbuf->v, sbuf->l);
18181c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		/* ensures that the modified buffer will be sent back to the caller, so
18191c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * add_recvdpkt() will add the correct buffer
18201c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 */
18211c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		swap = *sbuf;
18221c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		*sbuf = *vbuf;
18231c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		*vbuf = swap;
18241c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		vfree(vbuf);
18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* select the socket to be sent */
18290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	s = getsockmyaddr(iph1->local);
18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (s == -1){
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l,
18350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	      saddr2str_fromto("from %s to %s", iph1->local, iph1->remote));
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) {
18390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_sendfrags(iph1, sbuf) == -1) {
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "isakmp_sendfrags failed\n");
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
18450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = sendfromto(s, sbuf->v, sbuf->l,
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    iph1->local, iph1->remote, lcconf->count_persend);
18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (len == -1) {
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
18600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
18610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1resend_stub(p)
18620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
18630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
18650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1=(struct ph1handle *)p;
18670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(isakmp_ph1resend(iph1) < 0){
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(iph1->scr != NULL){
18690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Should not happen...
18700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sched_kill(iph1->scr);
18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->scr=NULL;
18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1resend(iph1)
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function
18850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->retry_counter <= 0) {
18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase1 negotiation failed due to time up. %s\n",
18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_pindex(&iph1->index, iph1->msgid));
18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVT_PUSH(iph1->local, iph1->remote,
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    EVTT_PEER_NO_RESPONSE, NULL);
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_send(iph1, iph1->sendbuf) < 0){
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "phase1 negotiation failed due to send error. %s\n",
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 isakmp_pindex(&iph1->index, iph1->msgid));
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVT_PUSH(iph1->local, iph1->remote,
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 EVTT_PEER_NO_RESPONSE, NULL);
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"resend phase1 packet %s\n",
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_pindex(&iph1->index, iph1->msgid));
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->retry_counter--;
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->scr = sched_new(iph1->rmconf->retry_interval,
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_ph1resend_stub, iph1);
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2resend_stub(p)
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2=(struct ph2handle *)p;
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(isakmp_ph2resend(iph2) < 0){
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2);
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2resend(iph2)
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->ph1->status == PHASE1ST_EXPIRED){
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed due to phase1 expired. %s\n",
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->retry_counter <= 0) {
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed due to time up. %s\n",
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2);
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed due to send error. %s\n",
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"resend phase2 packet %s\n",
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_pindex(&iph2->ph1->index, iph2->msgid));
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->retry_counter--;
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->scr = sched_new(iph2->ph1->rmconf->retry_interval,
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_ph2resend_stub, iph2);
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1expire_stub(p)
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_ph1expire((struct ph1handle *)p);
19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1expire(iph1)
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph1->sce);
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(iph1->status != PHASE1ST_EXPIRED){
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = racoon_strdup(saddr2str(iph1->local));
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = racoon_strdup(saddr2str(iph1->remote));
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(src);
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		STRDUP_FATAL(dst);
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "ISAKMP-SA expired %s-%s spi:%s\n",
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 src, dst,
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 isakmp_pindex(&iph1->index, 0));
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(src);
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(dst);
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->status = PHASE1ST_EXPIRED;
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * the phase1 deletion is postponed until there is no phase2.
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->sce = sched_new(1, isakmp_ph1expire_stub, iph1);
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1delete_stub(p)
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_ph1delete((struct ph1handle *)p);
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1delete(iph1)
20300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph1->sce);
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
20390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* don't re-negosiation when the phase 1 SA expires. */
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddr2str(iph1->local));
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddr2str(iph1->remote));
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"ISAKMP-SA deleted %s-%s spi:%s\n",
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src, dst, isakmp_pindex(&iph1->index, 0));
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph1(iph1);
20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph1(iph1);
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler.
20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function will call only isakmp_ph2delete().
20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * phase 2 handler remain forever if kernel doesn't cry a expire of phase 2 SA
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * by something cause.  That's why this function is called after phase 2 SA
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * expires in the userland.
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2expire_stub(p)
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_ph2expire((struct ph2handle *)p);
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2expire(iph2)
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->sce);
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddrwop2str(iph2->src));
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddrwop2str(iph2->dst));
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2 sa expired %s-%s\n", src, dst);
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_EXPIRED;
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2delete_stub(p)
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_ph2delete((struct ph2handle *)p);
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2delete(iph2)
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->sce);
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddrwop2str(iph2->src));
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddrwop2str(iph2->dst));
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2 sa deleted %s-%s\n", src, dst);
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unbindph12(iph2);
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%%
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Interface between PF_KEYv2 and ISAKMP
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive ACQUIRE from kernel, and begin either phase1 or phase2.
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * if phase1 has been finished, begin phase2.
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_post_acquire(iph2)
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1 = NULL;
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n");
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* search appropreate configuration with masking port. */
21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rmconf = getrmconf(iph2->dst);
21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rmconf == NULL) {
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no configuration found for %s.\n",
21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddrwop2str(iph2->dst));
21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* if passive mode, ignore the acquire message */
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rmconf->passive) {
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because of passive mode, "
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore the acquire message for %s.\n",
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddrwop2str(iph2->dst));
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Search isakmp status table by address and port
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * If NAT-T is in use, consider null ports as a
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * wildcard and use IKE ports instead.
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(iph2->src, extract_port(iph1->local));
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(iph2->dst, extract_port(iph1->remote));
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no ISAKMP-SA found. */
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL) {
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sched *sc;
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->retry_checkph1 = lcconf->retry_checkph1;
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sc = sched_new(1, isakmp_chkph1there_stub, iph2);
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"IPsec-SA request for %s queued "
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"due to no phase1 found.\n",
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddrwop2str(iph2->dst));
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* start phase 1 negotiation as a initiator. */
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) < 0) {
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			SCHED_KILL(sc);
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*NOTREACHED*/
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found ISAKMP-SA, but on negotiation. */
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->status != PHASE1ST_ESTABLISHED) {
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->retry_checkph1 = lcconf->retry_checkph1;
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sched_new(1, isakmp_chkph1there_stub, iph2);
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, iph2->dst,
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"request for establishing IPsec-SA was queued "
22130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"due to no phase1 found.\n");
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
22150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*NOTREACHED*/
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found established ISAKMP-SA */
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* i.e. iph1->status == PHASE1ST_ESTABLISHED */
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found ISAKMP-SA. */
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* begin quick mode */
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_ph2begin_i(iph1, iph2))
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive GETSPI from kernel.
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_post_getspi(iph2)
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* don't process it because there is no suitable phase1-sa. */
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->ph1->status == PHASE1ST_EXPIRED) {
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"the negotiation is stopped, "
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because there is no suitable ISAKMP-SA.\n");
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph2->side]
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph2->status])(iph2, NULL) != 0)
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2",
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called by scheduler */
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_chkph1there_stub(p)
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_chkph1there((struct ph2handle *)p);
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_chkph1there(iph2)
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->retry_checkph1--;
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->retry_checkph1 < 0) {
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->dst,
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase2 negotiation failed "
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"due to time up waiting for phase1. %s\n",
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(iph2->dst, iph2->src,
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph2->satype, 0, 0));
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"delete phase 2 handler.\n");
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* send acquire to kernel as error */
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pk_sendeacquire(iph2);
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2);
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
23000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Search isakmp status table by address and port
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * If NAT-T is in use, consider null ports as a
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * wildcard and use IKE ports instead.
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: extract_port.\n");
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if( (iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL){
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found a ph1 wop.\n");
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: searching byaddr.\n");
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(iph1 != NULL)
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found byaddr.\n");
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX Even if ph1 as responder is there, should we not start
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * phase 2 negotiation ? */
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 != NULL
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 && iph1->status == PHASE1ST_ESTABLISHED) {
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* found isakmp-sa */
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local));
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote));
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "before:\n");
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph2->src, extract_port(iph1->local));
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph2->dst, extract_port(iph1->remote));
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG2, LOCATION, NULL, "After:\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
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* begin quick mode */
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)isakmp_ph2begin_i(iph1, iph2);
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no isakmp-sa found */
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sched_new(1, isakmp_chkph1there_stub, iph2);
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* copy variable data into ALLOCATED buffer. */
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_set_attr_v(buf, type, val, len)
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
23580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t val;
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)buf;
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)len);
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data + 1, val, len);
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf + sizeof(*data) + len;
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* copy fixed length data into ALLOCATED buffer. */
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_set_attr_l(buf, type, val)
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t val;
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)buf;
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)val);
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf + sizeof(*data);
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* add a variable data attribute to the buffer by reallocating it. */
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_add_attr_v(buf0, type, val, len)
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf0;
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t val;
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int oldlen = 0;
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sizeof(*data) + len;
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf0) {
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		oldlen = buf0->l;
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vrealloc(buf0, oldlen + tlen);
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vmalloc(tlen);
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get a attribute buffer.\n");
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)(buf->v + oldlen);
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)len);
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(data + 1, val, len);
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* add a fixed data attribute to the buffer by reallocating it. */
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_add_attr_l(buf0, type, val)
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf0;
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t val;
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *data;
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int oldlen = 0;
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sizeof(*data);
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf0) {
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		oldlen = buf0->l;
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vrealloc(buf0, oldlen + tlen);
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vmalloc(tlen);
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get a attribute buffer.\n");
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (struct isakmp_data *)(buf->v + oldlen);
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data->lorv = htons((u_int16_t)val);
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * calculate cookie and set.
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_newcookie(place, remote, local)
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t place;
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote;
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *local;
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL, *buf2 = NULL;
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *p;
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int blen;
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int alen;
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t sa1, sa2;
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	time_t t;
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_short port;
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (remote->sa_family != local->sa_family) {
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"address family mismatch, remote:%d local:%d\n",
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remote->sa_family, local->sa_family);
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (remote->sa_family) {
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET:
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		alen = sizeof(struct in_addr);
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa1 = (caddr_t)&((struct sockaddr_in *)remote)->sin_addr;
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa2 = (caddr_t)&((struct sockaddr_in *)local)->sin_addr;
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET6:
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		alen = sizeof(struct in6_addr);
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa1 = (caddr_t)&((struct sockaddr_in6 *)remote)->sin6_addr;
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa2 = (caddr_t)&((struct sockaddr_in6 *)local)->sin6_addr;
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid family: %d\n", remote->sa_family);
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen = (alen + sizeof(u_short)) * 2
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		+ sizeof(time_t) + lcconf->secret_size;
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = vmalloc(blen);
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL) {
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get a cookie.\n");
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = buf->v;
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy my address */
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, sa1, alen);
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += alen;
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port = ((struct sockaddr_in *)remote)->sin_port;
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, &port, sizeof(u_short));
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(u_short);
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy target address */
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, sa2, alen);
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += alen;
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port = ((struct sockaddr_in *)local)->sin_port;
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, &port, sizeof(u_short));
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(u_short);
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy time */
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	t = time(0);
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, (caddr_t)&t, sizeof(t));
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(t);
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy random value */
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf2 = eay_set_random(lcconf->secret_size);
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf2 == NULL)
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, buf2->v, lcconf->secret_size);
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += lcconf->secret_size;
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(buf2);
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf2 = eay_sha1_one(buf);
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(place, buf2->v, sizeof(cookie_t));
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa1 = val2str(place, sizeof (cookie_t));
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "new cookie:\n%s\n", sa1);
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(sa1);
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf2 != NULL)
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf2);
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * save partner's(payload) data into phhandle.
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_p2ph(buf, gen)
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **buf;
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX to be checked in each functions for logging. */
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*buf) {
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore this payload, same payload type exist.\n");
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*buf = vmalloc(ntohs(gen->len) - sizeof(*gen));
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*buf == NULL) {
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer.\n");
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy((*buf)->v, gen + 1, (*buf)->l);
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_newmsgid2(iph1)
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t msgid2;
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	do {
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msgid2 = eay_random();
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} while (getph2bymsgid(iph1, msgid2));
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return msgid2;
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp header for phase 1
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic caddr_t
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid)
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vbuf;
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t etype;
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t flags;
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t msgid;
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp;
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (vbuf->l < sizeof(*isakmp))
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp = (struct isakmp *)vbuf->v;
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->np = nptype;
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->v = iph1->version;
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->etype = etype;
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->flags = flags;
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->msgid = msgid;
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp->len = htonl(vbuf->l);
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return vbuf->v + sizeof(*isakmp);
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp header for phase 1
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_header1(vbuf, iph1, nptype)
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vbuf;
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
26270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid);
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp header for phase 2
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_header2(vbuf, iph2, nptype)
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vbuf;
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid);
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set values into allocated buffer of isakmp payload.
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_isakmp_payload(buf, src, nptype)
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src;
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int nptype;
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_gen *gen;
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "add payload of len %zu, next type %d\n",
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    src->l, nptype);
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen = (struct isakmp_gen *)p;
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen->np = nptype;
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen->len = htons(sizeof(*gen) + src->l);
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += sizeof(*gen);
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(p, src->v, src->l);
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += src->l;
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return p;
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangetypesw1(etype)
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int etype;
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (etype) {
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_IDENT:
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_AGG:
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 2;
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_BASE:
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 3;
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangetypesw2(etype)
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int etype;
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (etype) {
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_QUICK:
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* for print-isakmp.c */
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *snapend;
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangextern void isakmp_print __P((const u_char *, u_int, const u_char *));
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *getname __P((const u_char *));
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *getname6 __P((const u_char *));
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint safeputchar __P((int));
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return a name for the IP address pointed to by ap.  This address
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is assumed to be in network byte order.
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetname(ap)
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_char *ap;
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in addr;
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char ntop_buf[NI_MAXHOST];
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&addr, 0, sizeof(addr));
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin_len = sizeof(struct sockaddr_in);
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin_family = AF_INET;
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&addr.sin_addr, ap, sizeof(addr.sin_addr));
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getnameinfo((struct sockaddr *)&addr, sizeof(addr),
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ntop_buf, sizeof(ntop_buf), NULL, 0,
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NI_NUMERICHOST | niflags))
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strlcpy(ntop_buf, "?", sizeof(ntop_buf));
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ntop_buf;
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return a name for the IP6 address pointed to by ap.  This address
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * is assumed to be in network byte order.
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetname6(ap)
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_char *ap;
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in6 addr;
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char ntop_buf[NI_MAXHOST];
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&addr, 0, sizeof(addr));
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin6_len = sizeof(struct sockaddr_in6);
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr.sin6_family = AF_INET6;
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&addr.sin6_addr, ap, sizeof(addr.sin6_addr));
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getnameinfo((struct sockaddr *)&addr, addr.sin6_len,
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ntop_buf, sizeof(ntop_buf), NULL, 0,
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NI_NUMERICHOST | niflags))
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strlcpy(ntop_buf, "?", sizeof(ntop_buf));
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ntop_buf;
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* INET6 */
27590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
27610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsafeputchar(c)
27620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int c;
27630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned char ch;
27650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ch = (unsigned char)(c & 0xff);
27670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (c < 0x80 && isprint(c))
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return printf("%c", c & 0xff);
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return printf("\\%03o", c & 0xff);
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
27740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_printpacket(msg, from, my, decoded)
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *from;
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *my;
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int decoded;
27790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef YIPS_DEBUG
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval tv;
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int s;
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char hostbuf[NI_MAXHOST];
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char portbuf[NI_MAXSERV];
27850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp;
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (loglevel < LLV_DEBUG)
27900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
27910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef YIPS_DEBUG
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&tv, NULL);
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	s = tv.tv_sec % 3600;
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf("%02d:%02d.%06u ", s / 60, s % 60, (u_int32_t)tv.tv_usec);
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (from) {
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (getnameinfo(from, sysdep_sa_len(from), hostbuf, sizeof(hostbuf),
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				portbuf, sizeof(portbuf),
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(hostbuf, "?", sizeof(hostbuf));
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(portbuf, "?", sizeof(portbuf));
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("%s:%s", hostbuf, portbuf);
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("?");
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf(" -> ");
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (my) {
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (getnameinfo(my, sysdep_sa_len(my), hostbuf, sizeof(hostbuf),
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				portbuf, sizeof(portbuf),
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(hostbuf, "?", sizeof(hostbuf));
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strlcpy(portbuf, "?", sizeof(portbuf));
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("%s:%s", hostbuf, portbuf);
28180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else
28190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("?");
28200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf(": ");
28210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = vdup(msg);
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printf("(malloc fail)\n");
28250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
28260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (decoded) {
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp = (struct isakmp *)buf->v;
28290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->flags & ISAKMP_FLAG_E) {
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
28310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int pad;
28320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pad = *(u_char *)(buf->v + buf->l - 1);
28330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (buf->l < pad && 2 < vflag)
28340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				printf("(wrong padding)");
28350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
28360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp->flags &= ~ISAKMP_FLAG_E;
28370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	snapend = buf->v + buf->l;
28410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_print(buf->v, buf->l, NULL);
28420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(buf);
28430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printf("\n");
28440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fflush(stdout);
28450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
28470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
28480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /*HAVE_PRINT_ISAKMP_C*/
28500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
28520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcopy_ph1addresses(iph1, rmconf, remote, local)
28530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
28540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
28550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
28560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t port;
28580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* address portion must be grabbed from real remote address "remote" */
28600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->remote = dupsaddr(remote);
28610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->remote == NULL)
28620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
28630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
28650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * if remote has no port # (in case of initiator - from ACQUIRE msg)
28660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * - if remote.conf specifies port #, use that
28670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * - if remote.conf does not, use 500
28680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * if remote has port # (in case of responder - from recvfrom(2))
28690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * respect content of "remote".
28700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
28710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port(iph1->remote) == 0) {
28720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port = extract_port(rmconf->remote);
28730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (port == 0)
28740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			port = PORT_ISAKMP;
28750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph1->remote, port);
28760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (local == NULL)
28790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->local = getlocaladdr(iph1->remote);
28800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
28810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->local = dupsaddr(local);
28820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->local == NULL)
28830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
28840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port(iph1->local) == 0)
28860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(iph1->local, PORT_ISAKMP);
28870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
28890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port(iph1->local) == lcconf->port_isakmp_natt) {
28900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n");
28910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER;
28920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
28940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
28960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
28990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnostate1(iph1, msg)
29000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
29010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
29020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, iph1->remote, "wrong state %u.\n",
29040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->status);
29050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
29060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
29090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnostate2(iph2, msg)
29100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
29110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
29120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "wrong state %u.\n",
29140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->status);
29150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
29160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
29190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanglog_ph1established(iph1)
29200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct ph1handle *iph1;
29210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *src, *dst;
29230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = racoon_strdup(saddr2str(iph1->local));
29250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = racoon_strdup(saddr2str(iph1->remote));
29260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(src);
29270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(dst);
29280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
29300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"ISAKMP-SA established %s-%s spi:%s\n",
29310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src, dst,
29320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_pindex(&iph1->index, 0));
29330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
29350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(!iph1->rmconf->mode_cfg)
29360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
29370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(src);
29390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(dst);
29400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
29420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct payload_list *
29450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_type)
29460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (! plist) {
29480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist = racoon_malloc (sizeof (struct payload_list));
29490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist->prev = NULL;
29500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else {
29520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist->next = racoon_malloc (sizeof (struct payload_list));
29530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist->next->prev = plist;
29540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plist = plist->next;
29550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plist->next = NULL;
29580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plist->payload = payload;
29590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plist->payload_type = payload_type;
29600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return plist;
29620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
29650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
29660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct payload_list *ptr = *plist, *first;
29680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t tlen = sizeof (struct isakmp), n = 0;
29690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
29700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *p;
29710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Seek to the first item.  */
29730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (ptr->prev) ptr = ptr->prev;
29740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	first = ptr;
29750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Compute the whole length.  */
29770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (ptr) {
29780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen += ptr->payload->l + sizeof (struct isakmp_gen);
29790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ptr = ptr->next;
29800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = vmalloc(tlen);
29830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL) {
29840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
29850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer to send.\n");
29860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
29870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ptr = first;
29900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = set_isakmp_header1(buf, iph1, ptr->payload_type);
29920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
29930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
29940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (ptr)
29960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
29970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE);
29980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		first = ptr;
29990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ptr = ptr->next;
30000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free (first);
30010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ptr->prev = NULL; first = NULL; ... omitted.  */
30020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n++;
30030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*plist = NULL;
30060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
30080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
30090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
30100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
30110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
30120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
30130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
30150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
30160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfrag_handler(iph1, msg, remote, local)
30170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
30180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
30190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote;
30200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *local;
30210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
30220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newmsg;
30230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_frag_extract(iph1, msg) == 1) {
30250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
30260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
30270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Packet reassembly failed\n");
30280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
30290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return isakmp_main(newmsg, remote, local);
30310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
30340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
30350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
30380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangscript_hook(iph1, script)
30390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
30400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int script;
30410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
30420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define IP_MAX 40
30430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define PORT_MAX 6
30440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char addrstr[IP_MAX];
30450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char portstr[PORT_MAX];
30460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **envp = NULL;
30470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int envc = 1;
30480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in *sin;
30490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **c;
30500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL ||
30520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->rmconf == NULL ||
30530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->rmconf->script[script] == NULL)
30540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
30550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
30570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)isakmp_cfg_setenv(iph1, &envp, &envc);
30580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* local address */
30610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sin = (struct sockaddr_in *)iph1->local;
30620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
30630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
30640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) {
30660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n");
30670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
30680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (script_env_append(&envp, &envc, "LOCAL_PORT", portstr) != 0) {
30710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_PORT\n");
30720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
30730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Peer address */
30760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->remote != NULL) {
30770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sin = (struct sockaddr_in *)iph1->remote;
30780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
30790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
30800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (script_env_append(&envp, &envc,
30820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "REMOTE_ADDR", addrstr) != 0) {
30830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
30840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot set REMOTE_ADDR\n");
30850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
30860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (script_env_append(&envp, &envc,
30890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "REMOTE_PORT", portstr) != 0) {
30900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
30910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot set REMOTEL_PORT\n");
30920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
30930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (privsep_script_exec(iph1->rmconf->script[script]->v,
30970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    script, envp) != 0)
30980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
30990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Script %s execution failed\n", script_names[script]);
31000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
31020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (c = envp; *c; c++)
31030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(*c);
31040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(envp);
31060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
31080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangscript_env_append(envp, envc, name, value)
31120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char ***envp;
31130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *envc;
31140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *name;
31150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *value;
31160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *envitem;
31180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **newenvp;
31190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int newenvc;
31200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	envitem = racoon_malloc(strlen(name) + 1 + strlen(value) + 1);
31220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (envitem == NULL) {
31230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
31250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sprintf(envitem, "%s=%s", name, value);
31280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvc = (*envc) + 1;
31300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvp = racoon_realloc(*envp, newenvc * sizeof(char *));
31310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newenvp == NULL) {
31320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory: %s\n", strerror(errno));
31340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(envitem);
31350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvp[newenvc - 2] = envitem;
31390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newenvp[newenvc - 1] = NULL;
31400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*envp = newenvp;
31420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*envc = newenvc;
31430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
31440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangscript_exec(script, name, envp)
31480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *script;
31490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int name;
31500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *const envp[];
31510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *argv[] = { NULL, NULL, NULL };
31530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	argv[0] = script;
31550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	argv[1] = script_names[name];
31560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	argv[2] = NULL;
31570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (fork()) {
31590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0:
31600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		execve(argv[0], argv, envp);
31610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "execve(\"%s\") failed: %s\n",
31630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    argv[0], strerror(errno));
31640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		_exit(1);
31650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
31660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case -1:
31670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot fork: %s\n", strerror(errno));
31690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
31710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
31720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
31730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
31750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
31790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpurge_remote(iph1)
31800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
31810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
31830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg, *next, *end;
31840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
31850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
31860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t mhp[SADB_EXT_MAX + 1];
31870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id;
31880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
31890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *new_iph1;
31900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
31920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "purging ISAKMP-SA spi=%s.\n",
31930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 isakmp_pindex(&(iph1->index), iph1->msgid));
31940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Mark as expired. */
31960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->status = PHASE1ST_EXPIRED;
31970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check if we have another, still valid, phase1 SA. */
31990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new_iph1 = getph1byaddr(iph1->local, iph1->remote, 1);
32000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
32020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
32030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Keep all others phase2 SAs.
32040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
32050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
32060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == NULL) {
32070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
32080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pfkey_dump_sadb returned nothing.\n");
32090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
32100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)buf->v;
32130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	end = (struct sadb_msg *)(buf->v + buf->l);
32140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (msg < end) {
32160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
32170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
32180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
32190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg->sadb_msg_type != SADB_DUMP) {
32200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
32250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfkey_check (%s)\n", ipsec_strerror());
32270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
32320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!sa ||
32330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    !mhp[SADB_EXT_ADDRESS_SRC] ||
32340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    !mhp[SADB_EXT_ADDRESS_DST]) {
32350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
32390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
32400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->sadb_sa_state != SADB_SASTATE_LARVAL &&
32420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    sa->sadb_sa_state != SADB_SASTATE_MATURE &&
32430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    sa->sadb_sa_state != SADB_SASTATE_DYING) {
32440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
32490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * check in/outbound SAs.
32500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Select only SAs where src == local and dst == remote (outgoing)
32510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * or src == remote and dst == local (incoming).
32520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
32530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) &&
32540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) {
32550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg = next;
32560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
32570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
32600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
32610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Check if there is another valid ISAKMP-SA */
32630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new_iph1 != NULL) {
32640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2 == NULL) {
32660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* No handler... still send a pfkey_delete message, but log this !*/
32670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_INFO, LOCATION, NULL,
32680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"Unknown IPsec-SA spi=%u, hmmmm?\n",
32690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					ntohl(sa->sadb_sa_spi));
32700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}else{
32710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*
32730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 * If we have a new ph1, do not purge IPsec-SAs binded
32740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 *  to a different ISAKMP-SA
32750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 */
32760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (iph2->ph1 != NULL && iph2->ph1 != iph1){
32770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					msg = next;
32780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					continue;
32790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
32800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* If the ph2handle is established, do not purge IPsec-SA */
32820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (iph2->status == PHASE2ST_ESTABLISHED ||
32830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					iph2->status == PHASE2ST_EXPIRED) {
32840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_INFO, LOCATION, NULL,
32860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n",
32870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 ntohl(sa->sadb_sa_spi),
32880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						 isakmp_pindex(&(new_iph1->index), new_iph1->msgid));
32890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					msg = next;
32900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					continue;
32910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
32920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
32930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pfkey_send_delete(lcconf->sock_pfkey,
32970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				  msg->sadb_msg_satype,
32980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				  IPSEC_MODE_ANY,
32990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				  src, dst, sa->sadb_sa_spi);
33000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* delete a relative phase 2 handle. */
33020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2 != NULL) {
33030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delete_spd(iph2, 0);
33040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			unbindph12(iph2);
33050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
33060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
33070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
33080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
33100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "purged IPsec-SA spi=%u.\n",
33110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 ntohl(sa->sadb_sa_spi));
33120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msg = next;
33140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
33150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
33170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
33180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Mark the phase1 handler as EXPIRED */
33200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
33210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "purged ISAKMP-SA spi=%s.\n",
33220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 isakmp_pindex(&(iph1->index), iph1->msgid));
33230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph1->sce);
33250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
33270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
33300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdelete_spd(iph2, created)
33310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
33320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 	u_int64_t created;
33330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
33350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage addr;
33360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t pref;
33370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src;
33380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *dst;
33390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
33400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */
33410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL)
33430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
33440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Delete the SPD entry if we generated it
33460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
33470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (! iph2->generated_spidx )
33480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
33490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = iph2->src;
33510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = iph2->dst;
33520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
33540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "generated policy, deleting it.\n");
33550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&spidx, 0, sizeof(spidx));
33570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->spidx_gen = (caddr_t )&spidx;
33580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make inbound policy */
33600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->src = dst;
33610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->dst = src;
33620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dir = IPSEC_DIR_INBOUND;
33630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.ul_proto = 0;
33640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
33660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Note: code from get_proposal_r
33670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
33680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
33700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
33720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * make destination address in spidx from either ID payload
33730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * or phase 1 address into a address in spidx.
33740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
33750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id != NULL
33760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&& (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
33770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
33780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
33790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
33800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get a destination address of a policy */
33810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = ipsecdoi_id2sockaddr(iph2->id,
33820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang									 (struct sockaddr *)&spidx.dst,
33830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang									 &spidx.prefd, &spidx.ul_proto);
33840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error)
33850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto purge;
33860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
33880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
33890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * get scopeid from the SA address.
33900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * note that the phase 1 source address is used as
33910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * a destination address to search for a inbound
33920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * policy entry because rcoon is responder.
33930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
33940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
33950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((error =
33960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 setscopeid((struct sockaddr *)&spidx.dst,
33970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							iph2->src)) != 0)
33980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
33990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
34030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
34040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			idi2type = _XIDT(iph2->id);
34050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
34070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "get a destination address of SP index "
34100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "from phase1 address "
34110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "due to no ID payloads found "
34120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "OR because ID type is not address.\n");
34130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
34150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * copy the SOURCE address of IKE into the
34160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * DESTINATION address of the key to search the
34170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * SPD because the direction of policy is inbound.
34180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
34190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
34200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (spidx.dst.ss_family) {
34210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
34220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefd =
34230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in_addr) << 3;
34240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
34270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefd =
34280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in6_addr) << 3;
34290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
34320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefd = 0;
34330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
34360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make source address in spidx */
34380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id_p != NULL
34390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&& (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
34400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
34410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
34420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
34430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get a source address of inbound SA */
34440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = ipsecdoi_id2sockaddr(iph2->id_p,
34450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang									 (struct sockaddr *)&spidx.src,
34460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang									 &spidx.prefs, &spidx.ul_proto);
34470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error)
34480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto purge;
34490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
34520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * get scopeid from the SA address.
34530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * for more detail, see above of this function.
34540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
34550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
34560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			error =
34570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				setscopeid((struct sockaddr *)&spidx.src,
34580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						   iph2->dst);
34590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (error)
34600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* make id[src,dst] if both ID types are IP address and same */
34650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (_XIDT(iph2->id_p) == idi2type
34660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&& spidx.dst.ss_family == spidx.src.ss_family) {
34670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->src_id =
34680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				dupsaddr((struct sockaddr *)&spidx.dst);
34690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->src_id == NULL) {
34700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
34710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					 "allocation failed\n");
34720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
34740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->dst_id =
34750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				dupsaddr((struct sockaddr *)&spidx.src);
34760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->dst_id == NULL) {
34770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
34780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					 "allocation failed\n");
34790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
34800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
34810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
34840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "get a source address of SP index "
34860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "from phase1 address "
34870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "due to no ID payloads found "
34880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "OR because ID type is not address.\n");
34890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* see above comment. */
34910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
34920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (spidx.src.ss_family) {
34930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
34940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefs =
34950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in_addr) << 3;
34960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
34990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefs =
35000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sizeof(struct in6_addr) << 3;
35010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
35030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
35040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx.prefs = 0;
35050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef _XIDT
35100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
35120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "get a src address from ID payload "
35130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "%s prefixlen=%u ul_proto=%u\n",
35140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 saddr2str((struct sockaddr *)&spidx.src),
35150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 spidx.prefs, spidx.ul_proto);
35160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
35170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "get dst address from ID payload "
35180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 "%s prefixlen=%u ul_proto=%u\n",
35190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 saddr2str((struct sockaddr *)&spidx.dst),
35200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 spidx.prefd, spidx.ul_proto);
35210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
35230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * convert the ul_proto if it is 0
35240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because 0 in ID payload means a wild card.
35250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
35260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spidx.ul_proto == 0)
35270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.ul_proto = IPSEC_ULPROTO_ANY;
35280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef _XIDT
35300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check if the generated SPD has the same timestamp as the SA.
35320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * If timestamps are different, this means that the SPD entry has been
35330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * refreshed by another SA, and should NOT be deleted with the current SA.
35340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
35350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if( created ){
35360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct secpolicy *p;
35370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = getsp(&spidx);
35390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(p != NULL){
35400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* just do no test if p is NULL, because this probably just means
35410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * that the policy has already be deleted for some reason.
35420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
35430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if(p->spidx.created != created)
35440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto purge;
35450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* End of code from get_proposal_r
35490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
35500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pk_sendspddelete(iph2) < 0) {
35520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
35530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(inbound) failed.\n");
35540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}else{
35550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
35560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(inbound) sent.\n");
35570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_POLICY_FWD
35600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make forward policy if required */
35610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tunnel_mode_prop(iph2->approval)) {
35620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.dir = IPSEC_DIR_FWD;
35630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pk_sendspddelete(iph2) < 0) {
35640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
35650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "pfkey spddelete(forward) failed.\n");
35660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}else{
35670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
35680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "pfkey spddelete(forward) sent.\n");
35690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
35720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make outbound policy */
35740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->src = src;
35750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->dst = dst;
35760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dir = IPSEC_DIR_OUTBOUND;
35770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	addr = spidx.src;
35780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.src = spidx.dst;
35790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dst = addr;
35800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pref = spidx.prefs;
35810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefs = spidx.prefd;
35820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefd = pref;
35830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pk_sendspddelete(iph2) < 0) {
35850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
35860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(outbound) failed.\n");
35870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}else{
35880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
35890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "pfkey spddelete(outbound) sent.\n");
35900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpurge:
35920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->spidx_gen=NULL;
35930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
35940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
35970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
35980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetscopeid(sp_addr0, sa_addr0)
35990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *sp_addr0, *sa_addr0;
36000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
36010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_in6 *sp_addr, *sa_addr;
36020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_addr = (struct sockaddr_in6 *)sp_addr0;
36040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_addr = (struct sockaddr_in6 *)sa_addr0;
36050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr)
36070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr)
36080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr))
36090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
36100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* this check should not be here ? */
36120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa_addr->sin6_family != AF_INET6) {
36130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
36140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"can't get scope ID: family mismatch\n");
36150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
36160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
36190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
36200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"scope ID is not supported except of lladdr.\n");
36210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
36220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_addr->sin6_scope_id = sa_addr->sin6_scope_id;
36250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
36270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
36280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3629