ipsec-tools: back-port 0.7.3 to Android.

Lots of checks and features were added to ipsec-tools 0.8.0.
However, they broke the compatibility with existing VPN servers.
I was unable to fix all of them in 0.8.0, so I chose to port
0.7.3 back with the new VPN types we added in ICS release.

Bug: 6191668
Change-Id: I86a7218f7f5146d4a9b129d46c89839a82b0008f
diff --git a/ChangeLog b/ChangeLog
index b071e40..0bc2ef7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,574 +1,46 @@
-2011-03-17  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/oakley.c: fixed a memory leak in
-	  oakley_append_rmconf_cr() while generating plist. patch by Roman
-	  Hoog Antink <rha@open.ch>
-
-	* src/racoon/oakley.c: free name later, to avoid a memory use after
-	  free in oakley_check_certid(). also give iph1->remote to some plog()
-	  calls. patch by Roman Hoog Antink <rha@open.ch>
-
-	* src/racoon/oakley.c: fixed a memory leak in
-	  oakley_check_certid(). patch by Roman Hoog Antink <rha@open.ch>
-
-2011-03-15  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: isakmp.c, isakmp_inf.c, pfkey.c: directly call
-	  isakmp_ph1delete() instead of scheduling isakmp_ph1delete_stub(), as
-	  it is useless an can lead to memory access after free
-
-2011-03-14  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: grabmyaddr.c, handler.c, isakmp.c, isakmp_inf.c,
-	  isakmp_quick.c, nattraversal.c, pfkey.c, policy.c, sockmisc.c,
-	  sockmisc.h, throttle.c: Explicitly compare return value of
-	  cmpsaddr() against a return value define to make it more obvious
-	  what is the intended action. One more return value is also added, to
-	  fix comparison of security policy descriptors. Namely, getsp()
-	  should not allow wildcard matching (as the comment says, it does
-	  exact matching) - otherwise we get problems when kernel has generic
-	  policy with no ports, and a second similar policy with ports.
-
-2011-03-14  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: cfparse.y, isakmp_xauth.c, isakmp_xauth.h,
-	  remoteconf.c, remoteconf.h, rsalist.c, rsalist.h: avoid some
-	  memory leaks / free memory access when reloading conf and have
-	  inherited config. patch from Roman Hoog Antink <rha@open.ch>
-
-	* src/racoon/handler.c: removed an useless comment
-
-	* src/racoon/handler.c: check if we got RMCONF_ERR_MULTIPLE from
-	  getrmconf_by_ph1() in revalidate_ph1tree_rmconf()
-
-2011-03-11  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: handler.c, isakmp.c: directly delete a ph1 in
-	  remove_ph1-) instead of scheduling it, to avoid (completely ?) a
-	  race condition when reloading configuration
-
-2011-03-06  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/privsep.c: Quiet a gcc warning when strict-aliasing
-	  checks are enabled. Reported by Stephen Clark.
-
-2011-03-02  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/session.c: flush sainfo list when closing session.
-	  patch by Roman Hoog Antink <rha@open.ch>
-
-	* src/racoon/: remoteconf.c, rsalist.c, rsalist.h: free rsa
-	  structures when deleting a struct rmconf. patch by Roman Hoog Antink
-	  <rha@open.ch>
-
-	* src/racoon/: cfparse.y, remoteconf.c, remoteconf.h: free spspec
-	  when deleting a rmconf struct. patch by Roman Hoog Antink
-	  <rha@open.ch>
-
-	* src/racoon/: remoteconf.c, session.c: fixed some memory leaks in
-	  remoteconf. patch by Roman Hoog Antink <rha@open.ch>
-
-	* src/racoon/: cfparse.y, prsa_par.y: fixed some memory leaks
-	  during configuration parsing. patch by Roman Hoog Antink
-	  <rha@open.ch>
-
-2011-03-01  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: isakmp.c, pfkey.c: plog text fixes, patch from M E
-	  Andersson <debian@gisladisker.se>
-
-	* src/racoon/cfparse.y: reset yyerrorcount before doing parse
-	  stuff. patch by Roman Hoog Antink <rha@open.ch>
-
-2011-02-20  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/oakley.c: From Roman Hoog Antink <rha@open.ch>: Fix
-	  memory leak when using plain RSA key authentication.
-
-2011-02-11  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/plainrsa-gen.c: From Mats E Andersson
-	  <debian@gisladisker.se>: Fix fprintf format specifier usage from
-	  previous patch.
-
-2011-02-10  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/plainrsa-gen.c: From Mats Erik Andersson
-	  <debian@gisladisker.se>: Implement importing of RSA keys from PEM
-	  files.
-
-	* src/racoon/prsa_par.y: From M E Andersson
-	  <debian@gisladisker.se>: Fix parsing of restricted RSA key
-	  addresses.
-
-2011-02-02  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: cftoken.l, isakmp.c, remoteconf.h, sainfo.c,
-	  sainfo.h: store ph1id in an u_int32_t instead of a (signed)int.
-	  Patch from Christophe Carre
-
-2011-01-28  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: sainfo.c, sainfo.h, session.c: From Roman Hoog
-	  Antink <rha@open.ch>: Clean up sainfo reloading: rename the
-	  functions, and remove unneeded global variable.
-
-	* src/racoon/: remoteconf.c, remoteconf.h, session.c: From Roman
-	  Hoog Antink <rha@open.ch>: Clean up rmconf reloading: rename the
-	  functions, and remove unneeded global variable.
-
-	* src/racoon/plog.c: From Roman Hoog Antink <rha@open.ch>: Log
-	  remote IP address if available (slightly modified by tteras)
-
-2011-01-22  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/isakmp_inf.c: From Roman Hoog Antink <rha@open.ch>:
-	  Fixes a null pointer dereference that might occur after removing
-	  peers from the config and then reloading.
-
-2011-01-20  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/libipsec/pfkey.c: fixed a typo, it will now compile when
-	  KMADDRESS is defined. reported by Roman Hoog Antink (rha (at)
-	  open.ch)
-
-2010-12-28  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/handler.c: From Roman Hoog Antink <rha@open.ch>: Fix
-	  config reload to not delete too many phase 2 handles, because wrong
-	  chain field is used when enumerating the handles.
-
-2010-12-16  gdt
-
-	* src/racoon/oakley.c: When encountering a certificate where "ID
-	  mismatched with ASN1 SubjectName", and verify_identifier is off,
-	  don't raise an error.  This makes the behavior match the man page.
-
-	  Patch sent for review long ago:
-	    http://mail-index.netbsd.org/tech-security/2006/03/24/0000.html
-	  with no negative feedback received to date.
-
-2010-12-14  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/ipsec_doi.c: From Roman Hoog Antink <rha@open.ch>: Fix
-	  possible null derefence.
-
-2010-12-08  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/admin.c: Use separate SA addresses for phase2's
-	  created by admin command. The phase2 startup overwrites src/dst with
-	  ISAKMP ports if they are zero and we don't want that to happen for
-	  the SA ports.
-
-2010-12-08  joerg
-
-	* src/libipsec/pfkey.c: ANSIfy
-
-2010-12-07  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/isakmp_quick.c: Fix spacing and improve wording in
-	  some log messages.
-
-2010-12-03  Timo Teras <timo.teras@iki.fi>
-
-	* src/libipsec/ipsec_dump_policy.c: Recognize direction for Linux
-	  per-socket policies.
-
-	* src/: libipsec/libpfkey.h, libipsec/pfkey_dump.c, setkey/parse.y,
-	  setkey/setkey.8: Support GRE key as upper layer protocol
-	  specifier (will be supported in Linux kernel 2.6.38).
-
-	* src/racoon/grabmyaddr.c: Netlink deletion notification does not
-	  guarentee actual address deletion: it might still exist on some
-	  other interface. Make sure we do not unbind unless the address is
-	  really gone.
-
-2010-11-17  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: handler.c, handler.h, isakmp.c, isakmp_inf.c: Fix my
-	  previous patch to not call purge_remote() twice. Change the place
-	  where purge_remote() is called. This fixes also a possible crash
-	  from the same patch since ph1->remote can be NULL (when we are
-	  responder and config is not yet selected).
-
-2010-11-12  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: admin.c, isakmp.c, isakmp_var.h, pfkey.c:
-	  isakmp_post_acquire is now called from admin commands too, add a
-	  flag so admin commands can be used to establish even passive links
-	  on demand.
-
-	* src/racoon/isakmp.c: Purge all IPsec-SA's if the last main
-	  ISAKMP-SA for the node is deleted by remote request and the phase1
-	  rekeying is enabled (this will also trigger the new phase1_dead
-	  script hook).
-
-	* src/racoon/: handler.h, isakmp_inf.c: Improve DPD sequence checks
-	  to allow any reply within valid sequence window to be proof of
-	  livelyness. This can improves things if there's random packet
-	  delays, or if racoon is not getting enough CPU time.
-
-	* src/racoon/: admin.c, admin.h, kmpstat.c, racoonctl.c: Extern
-	  admin protocol to allow reply packets to exceed 64kb. E.g SA dumps
-	  with many established SAs can be easily over the limit.
-
-2010-10-22  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/grabmyaddr.c: Change Linux Netlink address monitoring
-	  to monitor local route changes.  This works around a kernel bug, and
-	  slightly improves behaviour on some special cases.
-
-2010-10-21  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: admin.c, evt.c, grabmyaddr.c, isakmp.c, pfkey.c,
-	  session.c, session.h: Introduce priorities for file descriptor
-	  polling mechanism and give priority to admin port. If admin port is
-	  used by ISAKMP-SA hook scripts they should be preferred, other wise
-	  heavy traffic can delay admin port requests considerably. This in
-	  turn may cause renegotiation loop for ISAKMP-SA. This is mostly
-	  useful for OpenNHRP setup, but can benefit other setups too.
-
-	* src/racoon/: admin.c, handler.c, handler.h: Remove
-	  initial-contact entry when all ISAKMP-SA are purged via adminport.
-	  This will avoid stale security associations if some of the delete
-	  notifications happens to get lost.
-
-2010-10-20  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/crypto_openssl.c: Use high-level openssl EVP and HMAC
-	  functions when possible: this allows openssl to perform hardware
-	  acceleration if available.
-
-	* src/racoon/: isakmp.c, isakmp_quick.c: Various improvements to
-	  error log messages and a few additional error log messages to
-	  improve diagnosing an error condition.
-
-	* src/racoon/grabmyaddr.c: Fix address comparison so we actually
-	  close sockets which were bound to IP-address that got deconfigured.
-
-2010-10-11  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/ipsec_doi.c: report a higher encryption key length in
-	  approval for OBEY / CLAIM / STRICT modes
-
-2010-09-27  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/isakmp_xauth.c: fixed some typos in logs (reported by
-	  fazaeli (at) sepehrs.com)
-
-2010-09-24  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/cftoken.l: fixed a fd leak, patch by getlaser (at)
-	  gmail.com
-
-2010-09-22  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/admin.c: get the correct length of username when
-	  processing ADMIN_LOGOUT_USER, patch by rweikusat (at) mssgmbh.com
-
-	* src/racoon/nattraversal.h: fixed a typo in macros, reported by
-	  marisp (at) mt.lv
-
-2010-09-21  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/isakmp_cfg.c: moved from utmp.h to utmpx.h (patch
-	  provided by marcin.cieslak (at) gmail.com)
-
-2010-09-08  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/remoteconf.c: fixed remoteconf selection when no ID
-	  specified in configuration, and added some debug to remoteconf
-	  selection
-
-2010-08-26  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/remoteconf.c: fix by Sergio.Gelato (at) astro.su.se:
-	  duplicate some dynamic values in duprmconf()
-
-2010-08-04  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/isakmp_cfg.c: fixed answer for IP4_SUBNET request
-
-2010-07-30  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/doc/FAQ: updated link to NetBSD's documentation
-
-2010-06-22  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Bump date for previous.
-
-2010-06-22  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: cfparse.y, cftoken.l, isakmp.c, isakmp_inf.c,
-	  racoon.conf.5, remoteconf.c, remoteconf.h: added a specific
-	  script hook when a dead peer is detected
-
-2010-06-04  Thomas Klausner <wiz@netbsd.org>
-
-	* src/setkey/setkey.8: New sentence, new line. Bump date for
-	  previous.
-
-2010-06-04  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/setkey/: parse.y, setkey.8, token.l: Added support for
-	  spdupdate command in setkey
-
-2010-04-07  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/libipsec/ipsec_strerror.c: by Eric Preston: fixed a typo
-
-2010-04-02  Christos Zoulas <christos@netbsd.org>
-
-	* src/: libipsec/pfkey_dump.c, racoon/backupsa.c: handle ctime
-	  returning NULL.
-
-2010-03-11  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/handler.c: PR/42363: Yasuoka Masahiko: Second part of
-	  the patch: iterate only on the phase2 handles that are bound by the
-	  given phase1 handle.
-
-2010-03-05  Timo Teras <timo.teras@iki.fi>
-
-	* src/: libipsec/ipsec_set_policy.3, racoon/privsep.c,
-	  racoon/doc/FAQ, setkey/setkey.8: From Stefan Bauer: Fix multiple
-	  typoes and manpage formatting errors.
-
-2010-03-04  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/session.c: From Pierre POMES: fixed admin port
-	  initialization
-
-2010-02-28  snj
-
-	* src/racoon/: sockmisc.c, sockmisc.h: Fight the ever-increasing
-	  size of src checkouts by spelling "useful" without an extra l.
-
-2010-02-09  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/: pfkey.c, proposal.h: Fix typo in comment.
-
-2010-01-17  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/sainfo.c: Free strdeupped string after using it. Found
-	  by cppcheck.
-
-	* src/racoon/: eaytest.c, ipsec_doi.c: Close file handles after
-	  using them. Found by cppcheck.
-
-2010-01-15  joerg
-
-	* src/setkey/setkey.8: Use .%U instead of .%O for URLs.
-
-2009-12-11  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/Makefile.am: From Paul Wernau: vmbuf.h was defined
-	  twice in the headers. Remove the redundant entry so new install tool
-	  does not complain about overwriting just installed file.
-
-2009-11-22  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/handler.c: PR/42363: Yasuoka Masahiko:
-
-	  racoon uses a wrong IPsec-SA handle that is for other peer in case
-	  it receives a ISAKMP message for IPsec-SA that has the same
-	  message-id as the message-id that is received before.
-
-	  racoon uses message-id to find the handle of IPsec-SA.  The
-	  message-id is a unique number for each peer, but different peers may
-	  use the same value.
-
-	  Different Windows Vista or Windows 7 peers seem to use the same
-	  message-id.  racoon can handle the first Windows's Phase-2, but it
-	  cannot handle the second Windows.  Because racoon misunderstands the
-	  message for the second Windows as the message for the first Windows.
-
-	  >Category:       bin >Synopsis:       racoon uses a wrong IPsec-SA
-	  that is for different peer >Confidential:   no >Severity:
-	  serious >Priority:       medium >Responsible:    bin-bug-people
-	  >State:          open >Class:          sw-bug >Submitter-Id:   net
-	  >Arrival-Date:   Sun Nov 22 18:25:00 +0000 2009 >Originator:
-	  yasuoka@iij.ad.jp
-
-2009-10-29  Christos Zoulas <christos@netbsd.org>
-
-	* src/setkey/token.l: use %option noinput nounput
-
-2009-10-28  Christos Zoulas <christos@netbsd.org>
-
-	* src/setkey/token.l: no unput
-
-2009-10-14  joerg
-
-	* src/libipsec/ipsec_set_policy.3: Do not use .Xo/.Xc to workaround
-	  ancient groff limits.
-
-	* src/setkey/setkey.8: Do not use .Xo/.Xc to work around ancient
-	  groff limits.  Fix markup.
-
-	* src/racoon/racoon.conf.5: Don't use .Xo/.Xc to work around
-	  ancient groff limits.  Set only one list type.
-
-2009-09-18  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: isakmp_agg.c, isakmp_ident.c: From Tomas Mraz: Fix
-	  gssapi error checking.
-
-2009-09-03  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: admin.c, handler.c, handler.h, isakmp.c,
-	  isakmp_var.h, pfkey.c: When rekeying phase2 use phase1 used to
-	  negotiate phase2 as a hint to select the phase1 for rekeying the new
-	  phase2.
-
-2009-09-01  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: nattraversal.c, racoon.conf.5, vendorid.c: Check
-	  nat_traversal configuration from remote configuration candidates
-	  when acting as responder. Enable NAT-T if any of the remote
-	  candidates have NAT-T enabled.
-
-	* src/racoon/remoteconf.c: Change remote conf matching level to
-	  matching score. This way one can override anonymous certificate
-	  block config with more exact "inhereted" IP specific block.
-
-	* src/racoon/: isakmp.c, racoon.conf.5: From Maik Broemme: export
-	  ISAKMP SA identity as REMOTE_ID for phase1 up script (trac #313).
-
-2009-08-24  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/oakley.c: fixed typo: algoriym -> algorithm
-
-2009-08-19  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/remoteconf.c: fixed address check in
-	  rmconf_match_type(), just check address with wildcard port
-
-2009-08-19  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/remoteconf.c: Have an enum for rmconf_match_type()
-	  return values to make the code a bit more readable.
-
-2009-08-18  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/oakley.c: typo: algoritym -> algorithm
-
-2009-08-17  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/libipsec/libpfkey.h: do not use SADB_X_NAT_T_NEW_MAPPING to
-	  check system support for NAT-T, as at least FreeBSD doesn't have
-	  this define anymore
-
-	* src/racoon/schedule.h: include stddef.h so we have a chance to
-	  get the system offsetof if present
-
-	* src/racoon/crypto_openssl.h: removed a self include
+2009-08-13  tag ipsec-tools-0_7_3
 
 2009-08-13  Yvan Vanhullebus <vanhu@netasq.com>
 
+	* NEWS, configure.ac: 0.7.3 release
+
 	* src/racoon/oakley.c: fixed a potential DoS in
 	  oakley_do_decrypt(), reported by Orange Labs
 
-2009-08-10  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/pfkey.c: Don't print EAGAIN error from
-	  pfkey_handler(), it can occur normally under some code paths and is
-	  not a hard error in any case.
-
 2009-08-06  Timo Teras <timo.teras@iki.fi>
 
 	* src/setkey/setkey.c: From Paul Wenau: Check fgets return value in
 	  setkey to make gcc happy.
 
-2009-08-05  Timo Teras <timo.teras@iki.fi>
+2009-06-19  Timo Teras <timo.teras@iki.fi>
 
-	* src/racoon/pfkey.c: From Paul Wernau: Fix transport mode per-port
-	  security associations that got broke during NAT-T fixes.
-
-2009-07-07  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/sockmisc.c: From Arnaud Ebalard: Fix possible usage of
-	  uninitialized local variable (not sure if any code path triggers
-	  this, but this makes compiler happy).
-
-2009-07-03  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: admin.c, grabmyaddr.c, handler.c, handler.h,
-	  isakmp.c, isakmp_cfg.c, isakmp_inf.c, isakmp_quick.c,
-	  nattraversal.c, pfkey.c, policy.c, remoteconf.c, remoteconf.h,
-	  sockmisc.c, sockmisc.h, throttle.c: Get rid of the evil CMPSADDR
-	  macro. Trac #295.
-
-	* src/: libipsec/libpfkey.h, libipsec/pfkey.c, racoon/isakmp.c,
-	  racoon/isakmp_inf.c, racoon/pfkey.c, racoon/pfkey.h: From Yvan
-	  Vanhullebus: Use SADB_X_EXT_NAT_T_* consistently for passing the
-	  NAT-T port information. This might break compatibility with some
-	  kernels, but as discussed this is the proper way to pass NAT-T ports
-	  and the broken kernels need to be fixed.
-
-2009-06-24  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/session.c: Fix a call to null pointer: in some cases,
-	  the unmonitor_fd can be called from another fd's callback. That
-	  could lead to still have callback pending after unmonitoring the fd
-	  resulting in a call to null pointer.  This is fixed by making
-	  unmonitor_fd now clear the pending fd_set too.  Bug was introduced
-	  by my commit in 2008-12-23.
-
-2009-05-20  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/isakmp.h: typo
-
-2009-05-19  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: ipsec_doi.c, isakmp.c: From Jukka Salmi: Fix couple
-	  of typos from previous commit.
+	* src/racoon/ipsec_doi.c: Backport S.P.Zeidler's fix to IPv6
+	  address related stack smashing in ipsecdoi_id2str() from CVS HEAD.
 
 2009-05-18  Timo Teras <timo.teras@iki.fi>
 
-	* src/racoon/: ipsec_doi.c, isakmp.c, sockmisc.c, sockmisc.h: From
-	  Tomas Mraz: Introduce union sockaddr_any and use it to make code
-	  more readable. Related to trac #293.
-
 	* src/racoon/isakmp_inf.c: From Tomas Mraz: Remove variable that is
 	  not really used; only referenced while uninitialized causing
 	  valgrind error.
 
 	* src/racoon/nattraversal.c: From Tomas Mraz: Fix natt_flags check.
 
-2009-05-04  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Remove superfluous spaces around
-	  parentheses.
-
 2009-04-29  Timo Teras <timo.teras@iki.fi>
 
 	* src/racoon/crypto_openssl.c: From Ross Meng: Fix a memory leak in
 	  X509 certificate validation.
 
-2009-04-28  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/handler.c: Reset nat_oa variables too when reusing
-	  phase two handler. Otherwise phase2 rekeying might fail in some
-	  scenarios.
+2009-04-22  tag ipsec-tools-0_7_2
 
 2009-04-22  Timo Teras <timo.teras@iki.fi>
 
+	* NEWS, configure.ac: Updates for 0.7.2 release
+
 	* src/racoon/isakmp_frag.c: From Neil Kettle: Fix a possible null
 	  pointer dereference in fragmentation code.
 
-2009-04-21  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: grabmyaddr.c, grabmyaddr.h, session.c: Fix
-	  strict_address to work again. The lists needs to be initialized
-	  before configuration is read, which happens before my_addr_init()
-	  call.
-
 2009-04-20  Timo Teras <timo.teras@iki.fi>
 
-	* src/racoon/: isakmp.c, isakmp.h, isakmp_var.h: Fix a memory leak
-	  in certificate request generation.
-
 	* src/racoon/: isakmp_inf.c, isakmp_xauth.c, plog.c: Orignally from
 	  Bin Li: Fix possible memory corruption in binsanitize().
 
@@ -584,257 +56,25 @@
 	* src/racoon/handler.c: From Paul Moore: Phase2 message id's should
 	  be unique wrt phase1, not globally.
 
-2009-03-13  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: pfkey.c, remoteconf.h: From Arnaud Ebalard: Fix
-	  couple of problems with previous commit.
-
-2009-03-12  he
-
-	* src/racoon/: isakmp.c, remoteconf.c: When casting to/from a
-	  pointer to an integral type (a bad practice, if you ask me), you
-	  need to cast via intptr_t for portability.
-
-2009-03-12  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: New sentence, new line. Avoid marking
-	  up punctuation.
-
-	* src/racoon/racoonctl.8: Bump date for previous. Sort options to
-	  establish-sa.  Stop using Xo/Xc.
-
-2009-03-12  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: admin.c, cfparse.y, cftoken.l, crypto_openssl.c,
-	  crypto_openssl.h, dnssec.c, dnssec.h, handler.c, handler.h,
-	  ipsec_doi.c, ipsec_doi.h, isakmp.c, isakmp.h, isakmp_agg.c,
-	  isakmp_base.c, isakmp_ident.c, isakmp_inf.c, isakmp_quick.c,
-	  isakmp_var.h, nattraversal.c, oakley.c, oakley.h, racoon.conf.5,
-	  racoonctl.8, racoonctl.c, remoteconf.c, remoteconf.h, sockmisc.c,
-	  vendorid.c: Support multiple anonymous remotes and decide
-	  remoteconf based on identity, received certificates and other
-	  information. General code clean up.
-
-2009-03-06  Timo Teras <timo.teras@iki.fi>
-
-	* src/setkey/: extern.h, parse.y, setkey.c: setkey: fix deleteall
-	  in Linux
-
-	  Linux requires SADB_DELETE message to have SPI. So send a
-	  SADB_DELETE message for each matching SA. Trac #284.
-
-	  From: Gabriel Somlo <somlo@cmu.edu>
-
 2009-02-16  Timo Teras <timo.teras@iki.fi>
 
 	* src/libipsec/policy_parse.y: From Paul Moore: Fix a heap
 	  corruption bug (yacc return non-null terminated buffer and sprintf
 	  writes over bounds).
 
-2009-02-11  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/: isakmp.c, sockmisc.c, sockmisc.h: trac#301: fixed
-	  IPsec SAs flush in purge_remote() when NAT-T enabled but no NAT-T on
-	  tunnel
-
-2009-02-03  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/isakmp.c: From: Phil Sutter. Fix script environment
-	  variables with IPv6 addresses.
-
-2009-01-26  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/main.c: Argument parsing needs lcconf initialized.
-
-2009-01-24  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoonctl.c: Sort options in usage.
-
-	* src/racoon/racoonctl.8: Sort options. New sentence, new line.
-
-	* src/racoon/racoon.8: Sort options.
-
-2009-01-23  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: racoonctl.8, racoonctl.c: Update usage and manpage
-	  for racoonctl.
-
-	* src/racoon/: main.c, racoon.8: Racoon -v to print version and
-	  compilation information. Update usage message.
-
-	* NEWS: Update NEWS with major changes since 0.7 release.
-
-	* src/racoon/schedule.c: Fix monotonic scheduler change, to not
-	  refresh 'now' before exit. Otherwise we can return negative timeout
-	  after spending time handling other events.
-
-	* src/racoon/: handler.c, pfkey.c: From Arnaud Ebalard: Handle
-	  reception of MIGRATE message during Phase 1 and Phase 2 negotiation.
-	  Also corrects some debugging statements.
-
-	* src/racoon/pfkey.c: From Arnaud Ebalard: On the responder (for
-	  instance), there is a need to not only migrate local and remote
-	  addresses of Phase 1 that match previous addresses but also the
-	  local and remote addresses of a Phase 1 *associated* with a migrated
-	  Phase 2. For instance, we have that need when receiving the first
-	  MIGRATE/KMADDRESS message because the old addresses are still the
-	  HoA and the address of the HA (while the peer has contacted us using
-	  the CoA and we have negotiated this address as src attribute in
-	  Phase 2). The patch fixes that by having migrate_ph1_ike_addresses()
-	  called from migrate_ph2_ike_addresses() callback.
-
-	* src/racoon/isakmp_quick.c: From Arnaud Ebalard: Set phase2 spid
-	  when acting as responder.
-
-	* configure.ac, src/racoon/handler.c, src/racoon/handler.h,
-	  src/racoon/isakmp_inf.c, src/racoon/isakmp_xauth.c,
-	  src/racoon/schedule.c, src/racoon/schedule.h,
-	  src/racoon/throttle.c, src/racoon/throttle.h: Detect if monotonic
-	  system clock is available, and use it for relative time measurements
-	  to avoid complite hang if time jumps backwards.
-
-	* src/racoon/: cfparse.y, ipsec_doi.c, isakmp.c, isakmp_agg.c,
-	  isakmp_base.c, isakmp_cfg.c, isakmp_ident.c, isakmp_xauth.c,
-	  oakley.c, oakley.h: Fix authentication method ambiguity by
-	  internally using unique ID and setting/interpreting the wire format
-	  based on received vendor ID:s. Fixes trac #280.
-
-	* src/racoon/: handler.h, isakmp_agg.c, isakmp_base.c,
-	  isakmp_ident.c, vendorid.c, vendorid.h: Introduce vendorid
-	  bitmask that can be used otherwhere to detect peer capabilities.
-
-	* configure.ac, src/racoon/admin.c, src/racoon/evt.c,
-	  src/racoon/grabmyaddr.c, src/racoon/isakmp.c, src/racoon/pfkey.c,
-	  src/racoon/session.c, src/racoon/session.h: Remove "fastquit"
-	  configure option and make it the default behaviour. The previous
-	  normal behaviour is buggy, as after flush kernel can immediately
-	  create larval SA:s which would prevent exit.
-
 2009-01-20  Timo Teras <timo.teras@iki.fi>
 
-	* Makefile.am, misc/cvs2cl.pl, misc/cvsusermap: Autogenerate
-	  ChangeLog from NetBSD CVS. Put sourceforge.net changes to
-	  ChangeLog.old.
-
-2009-01-10  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Make ready for HTML output.  Use proper
-	  escape for backslash ('\e').
-
-2009-01-10  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: crypto_openssl.c, racoon.conf.5: From Cyrus Rahman:
-	  Accept RFC2253 compliant escaped special characters for asn1dn
-	  identifier.
-
-2009-01-09  Timo Teras <timo.teras@iki.fi>
-
 	* configure.ac: Fix a CPPLAGS typo to CPPFLAGS which was intended
 
-2009-01-05  Timo Teras <timo.teras@iki.fi>
+	* misc/cvs2cl.pl, misc/cvsusermap, Makefile.am: Autogenerate
+	  ChangeLog from NetBSD CVS. Put sourceforge.net changes to
+	  ChangeLog.old.
 
-	* src/racoon/: cfparse.y, cftoken.l, racoon.conf.5: Remove obsolete
-	  configuration options, fix radius configuration block and add GRE as
-	  recognized protocol.
+	* misc/cvs2cl.pl: file cvs2cl.pl was added on branch
+	  ipsec-tools-0_7-branch on 2009-01-20 14:36:32 +0000
 
-	* src/racoon/session.c: Do not use counting in signal handling as
-	  it was unsafe by not using atomic functions (post increment is not
-	  necessarily atomic).  Instead reap all children on SIGCHLD as that
-	  was the only signal needing signal counting.
-
-2008-12-30  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/session.c: schedular() call can now modify fd mask so
-	  make the working copy just before calling select(); otherwise it can
-	  contain bad file descriptors
-
-2008-12-29  Michael van Elst <mlelstv@netbsd.org>
-
-	* src/setkey/parse.y: support icmp codes. Fixes PR 39056.
-
-2008-12-24  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/grabmyaddr.c: remove sin{6,}_len linux does not have
-	  it. From Timo Teras.
-
-	* src/racoon/grabmyaddr.c: I was wrong. addr is actually set.
-
-	* src/racoon/grabmyaddr.c:
-	  - make this compile by zeroing out the whole structure not just
-	  bogus fields.
-	  - set length field of sockets appropriately.
-	  - mark bogus no-op code (I don't understand what the author intended
-	  here).
-
-2008-12-23  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Bump date for identity configuration
-	  option removal.
-
-2008-12-23  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: cfparse.y, cftoken.l, ipsec_doi.c, localconf.c,
-	  localconf.h, racoon.conf.5: Remove the obsoleted global identity
-	  configuration option.
-
-	* src/racoon/: admin.c, admin_var.h, cfparse.y, debug.h, evt.c,
-	  evt.h, grabmyaddr.c, grabmyaddr.h, handler.c, isakmp.c,
-	  isakmp_inf.c, isakmp_var.h, localconf.c, localconf.h, main.c,
-	  nattraversal.c, pfkey.c, pfkey.h, privsep.c, session.c,
-	  session.h: rewrite local address detection make some functions
-	  static that arr not needed globally rework how fd_set is
-	  construction for the main loop select()
-
-2008-12-18  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/pfkey.c: From Arnaud Ebalard: Delete larval ph2handles
-	  when expire with hard lifetime received
-
-2008-12-16  Timo Teras <timo.teras@iki.fi>
-
-	* README: Update README
-
-	* src/racoon/pfkey.c: Fix transport mode address selection in
-	  acquire handling.  Some earlier fixes got lost on 2008-12-05 commit.
-
-2008-12-11  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/grabmyaddr.c: Fixed compilation on FreeBSD (RTM_IFINFO
-	  and RTM_OIFINFO stuff)
-
-	* src/racoon/isakmp.c: Fixed compilation when DPD support is
-	  disabled
-
-2008-12-08  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: pfkey.c, privsep.c, privsep.h: Do not cache pfkey
-	  sockets: it might cause to not handle some pfkey events when
-	  select() has marked pfkey socket readable, but a timer callback
-	  first calls pfkey_dump_sadb().
-
-2008-12-05  Timo Teras <timo.teras@iki.fi>
-
-	* src/: libipsec/key_debug.c, libipsec/libpfkey.h,
-	  libipsec/pfkey.c, racoon/handler.c, racoon/handler.h,
-	  racoon/ipsec_doi.c, racoon/isakmp.c, racoon/isakmp_quick.c,
-	  racoon/pfkey.c, racoon/policy.c, racoon/policy.h: From Arnaud
-	  Ebalard: Improved Mobile IPv6 support per
-	  draft-ebalard-mext-pfkey-enhanced-migrate.
-
-2008-12-04  Christoph Badura <bad@netbsd.org>
-
-	* src/racoon/privsep.c: Fix typo in previous and use SIG_IGN as I
-	  intended.
-
-2008-12-02  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/session.c: Explicitly ignore SIGPIPE. Default action
-	  on Linux is terminate.
-
-2008-11-28  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Remove empty line. Fix typo. New
-	  sentence, new line.
+	* misc/cvsusermap: file cvsusermap was added on branch
+	  ipsec-tools-0_7-branch on 2009-01-20 14:36:32 +0000
 
 2008-11-27  Yvan Vanhullebus <vanhu@netasq.com>
 
@@ -843,181 +83,26 @@
 
 	* src/racoon/isakmp_cfg.c: Fixed pool resizing
 
-2008-11-27  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/pfkey.c: From Arnaud Ebalard: Remove MAXNESTEDSA
-	  weirdness. It's probably meant for bundle support which is not done.
-	  When someone actually writes bundle support, the nested SA stuff
-	  would probably be reworked too anyway.
-
-	* src/: libipsec/libpfkey.h, libipsec/pfkey.c, racoon/cfparse.y,
-	  racoon/cftoken.l, racoon/localconf.c, racoon/localconf.h,
-	  racoon/pfkey.c, racoon/racoon.conf.5: From: Matthew Krenzer
-	  Ability to set pfkey socket buffer size via configuration file
-	  directive.  (Indentation and minor fixes by me.)
-
-2008-11-25  Christoph Badura <bad@netbsd.org>
-
-	* src/racoon/: evt.c, privsep.c, session.c: Avoid using
-	  MSG_NOSIGNAL as it is not available everywhere.  Ignore SIGPIPE
-	  instead.
-
-	* src/racoon/grabmyaddr.c: Ignore unspecified and looback
-	  addresses.  Ignoring unspecified addresses prevents racoon from
-	  trying to bind to the wildcard address and specific addresses
-	  simultaneously after e.g. dhclient has changed an interface's
-	  address to 0.0.0.0.
-
-	* src/racoon/grabmyaddr.c: RTM_DELETE and RTM_IFINFO don't carry
-	  info for added or deleted addresses.  Ignore them silently.
-
-	* src/racoon/grabmyaddr.c: Ignoring an unsuitable address is not an
-	  error.  Therefore log it as informational.  Make it clear from the
-	  log message that a route message is not interesting.
-
-	* src/racoon/grabmyaddr.c: Use insmyaddr() instead of open coding
-	  it.
-
-	* src/racoon/isakmp.c: Do not return erroneously from isakmp_open()
-	  when setting IPV6_USE_MIN_MTU fails.
-
-	* src/racoon/: grabmyaddr.c, isakmp.c: Keep myaddr.sock at -1 when
-	  no socket is opened.
-
-2008-11-08  Christoph Badura <bad@netbsd.org>
-
-	* src/racoon/samples/roadwarrior/client/: phase1-down.sh,
-	  phase1-up.sh: Preserve owner and permissions of original
-	  /etc/resolv.conf.  Ensure that new /etc/resolv.conf isn't group or
-	  world writable.
-
-	* src/racoon/samples/roadwarrior/client/: phase1-down.sh,
-	  phase1-up.sh: Print and check INTERNAL_NETMASK4.
-
-	* src/racoon/samples/roadwarrior/client/: phase1-down.sh,
-	  phase1-up.sh: Make the handling of NAT-T SPD entries automatic.
-
-	* src/racoon/samples/roadwarrior/client/: phase1-down.sh,
-	  phase1-up.sh: Ensure that the determination of the default
-	  gateway and the corresponding interface don't get confused by
-	  multiple, possibly non-IPv4  default routes.  Bring the NetBSD case
-	  of deleting the VPN routes and address in line with the Linux case
-	  and delete the address after deleting the VPN routes.
-
-2008-11-06  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/sainfo.c: fixed delsainfo() to avoid a crash when
-	  iddst's value is SAINFO_CLIENTADDR
-
-2008-10-29  S.P.Zeidler <spz@netbsd.org>
-
-	* src/racoon/ipsec_doi.c: Changes to ipsecdoi_id2str():
-
-	  struct sockaddr -> struct sockaddr_storage fixes a stack overflow
-
-	  For non-linklocal addresses the value in 'scope' is garbage and gets
-	  set to zero instead.
-
-2008-10-27  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/pfkey.c: From Arnaud Ebalard: Add missing return to
-	  error path
-
-	* src/racoon/grabmyaddr.c: From Francis Dupont (sent by Arnaud
-	  Ebalard): recognize RTM_IFANNOUNCE
-
-	* src/racoon/grabmyaddr.c: From Arnaud Ebalard: Fix indentation
-	  issues for readability
-
-	* src/racoon/session.c: From Arnaud Ebalard: initfds() needs to be
-	  called only if monitored file descriptor numbers have changed
-
-	* src/racoon/isakmp_var.h: From Arnaud Ebalard: Remove duplicate
-	  declaration
-
-2008-10-23  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: privsep.c, session.c, session.h: From Krzysztof
-	  Piotr Oledzki <olel@ans.pl>: Revert parts of 2008-08-06 commit; the
-	  problem those changes address are already handled in a sensible way
-	  by Cyrus Rahman's patch from 2008-03-06.
-
-2008-10-09  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/isakmp_quick.c: From Arnaud Ebalard: remove
-	  unnecessary unbindph12() call which is now done in remph2()
-
 2008-09-25  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/isakmp.c: Fixed resending mechanism to have non-ESP
 	  marker for retransmitted packets
 
-2008-09-19  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: New sentence, new line.
-
-2008-09-19  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: admin.c, cfparse.y, cftoken.l, handler.c, handler.h,
-	  isakmp.c, isakmp_cfg.c, isakmp_inf.c, isakmp_quick.c,
-	  isakmp_var.h, isakmp_xauth.c, pfkey.c, proposal.c, racoon.conf.5,
-	  remoteconf.c, remoteconf.h: Implement ISAKMP SA rekeying
-	  configurable with rekey {on|off|force} option in remote conf.
-
-	* src/racoon/: handler.c, handler.h, isakmp.c, isakmp_inf.c,
-	  isakmp_quick.c, isakmp_var.h, isakmp_xauth.c, isakmp_xauth.h,
-	  nattraversal.c, pfkey.c, pfkey.h, schedule.c, schedule.h,
-	  session.c: Change struct sched to be allocated be the caller to
-	  avoid some memory allocations. Optimize scheduling algorithm to not
-	  scan all entries in the main loop.
-
 2008-09-17  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/isakmp_inf.c: Fixed port match in purge_ipsec_spi()
 	  when NAT-T enabled and trying to purge non NAT-T SAs
 
-2008-09-09  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/pfkey.c: Some calls to set_port() were not correctly
-	  updated in the previous commit
-
-2008-09-03  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/pfkey.c: From Tomas Mraz: Duplicate addresses in
-	  pk_sendxxx functions, as they may be altered for NAT-T stuff.
-
-2008-09-03  Timo Teras <timo.teras@iki.fi>
-
-	* src/: libipsec/pfkey.c, racoon/pfkey.c, racoon/sockmisc.c:
-	  - Fix reloading of SPD (Linux satype check, handling of SPD dump
-	  responses)
-	  - Remove some spurious error log message from extract_port()
-
-2008-08-29  Gregory McGarry <gmcgarry@netbsd.org>
-
-	* src/racoon/isakmp.c: Eliminate gcc-specific feature of empty
-	  structures.
-
-	* src/racoon/evt.h: Eliminate superfluous semicolon.
-
-	* src/racoon/: admin.c, admin.h: Eliminate gcc-specific feature of
-	  unnamed structures added recently.
-
 2008-08-12  Yvan Vanhullebus <vanhu@netasq.com>
 
-	* src/racoon/isakmp.c: From Krzysztof Piotr Oledzki: Remove
-	  ph1handler if we received an invalid first exchange from initiator.
+	* src/racoon/isakmp.c: From Krzysztof Oledzki: Remove ph1handler if
+	  we received an invalid first exchange from initiator.
 
-2008-08-06  Timo Teras <timo.teras@iki.fi>
+2008-07-23  tag ipsec-tools-0_7_1
 
-	* src/racoon/: privsep.c, session.c, session.h: From Krzysztof
-	  Piotr Oledzki: Make privileged process exit if unprivileged process
-	  is terminated and some spelling fixes.
+2008-07-23  Yvan Vanhullebus <vanhu@netasq.com>
 
-2008-07-23  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/: cfparse.y, session.c: Add some missing ifdefs
-	  required for non-radius enabled builds.
+	* NEWS: NEWS for 0.7.1 release
 
 2008-07-23  Timo Teras <timo.teras@iki.fi>
 
@@ -1029,30 +114,16 @@
 
 2008-07-22  Yvan Vanhullebus <vanhu@netasq.com>
 
+	* configure.ac: 0.7.1 coming !
+
 	* src/racoon/proposal.c: From Kohki Ohhira: fix some memory leaks,
 	  when malloc fails or when peer sends invalid proposal.
 
-2008-07-22  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/: cfparse.y, cftoken.l, isakmp_cfg.c, isakmp_xauth.c,
-	  isakmp_xauth.h, main.c, racoon.conf.5, session.c: Add an optional
-	  radius configuration section to the racoon.conf file. This is
-	  similar to the the LDAP configuration section and overrides settings
-	  in the system radius configuration file.
-
-2008-07-21  Matthias Scheler <tron@netbsd.org>
+2008-07-21  Timo Teras <timo.teras@iki.fi>
 
 	* src/racoon/cfparse.y: Correct typo to fix the build.
 
-2008-07-21  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: isakmp_agg.c, isakmp_base.c, isakmp_ident.c,
-	  vendorid.c, vendorid.h: Separate generic vendor id handling to a
-	  new function and use it.
-
-	* src/racoon/cfparse.y: Do not set default gss id if xauth is used,
-	  otherwise gss-id attribute might be sent even if it was not
-	  requested.
+	* src/racoon/cfparse.y: Do not set default gss id if xauth is used.
 
 2008-07-15  Matthew Grooms <mgrooms@shrew.net>
 
@@ -1063,17 +134,6 @@
 	  racoonctl.c: Fix a conflict with the FreeBSD 8 system hexdump
 	  function.
 
-2008-07-14  Timo Teras <timo.teras@iki.fi>
-
-	* src/racoon/: handler.h, ipsec_doi.c, ipsec_doi.h, isakmp_quick.c,
-	  pfkey.c: Handle RESPONDER-LIFETIME notification in quick mode.
-
-	* src/racoon/: handler.h, isakmp.c, isakmp_agg.c, isakmp_ident.c,
-	  isakmp_inf.c, isakmp_inf.h, isakmp_quick.c, strnames.c: Clean up
-	  notification payload handling. Handle INITIAL-CONTACT notification
-	  in last main mode exchange (delayed) and during quick mode
-	  exchanges.
-
 2008-07-11  Timo Teras <timo.teras@iki.fi>
 
 	* src/racoon/: isakmp.c, isakmp_inf.c: Original patch from Atis
@@ -1087,125 +147,48 @@
 
 2008-07-02  Yvan Vanhullebus <vanhu@netasq.com>
 
-	* src/racoon/isakmp_inf.c: From Timo Teras: fix some %d to %zu
-	  (size_t values)
-
-2008-06-18  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoonctl.8: Bump date for previous.
+	* src/racoon/isakmp_inf.c: From Timo Teras: fixed some %d to %zu
+	  (size_t values).
 
 2008-06-18  Matthew Grooms <mgrooms@shrew.net>
 
-	* src/racoon/: admin.c, admin.h, racoonctl.8, racoonctl.c: Add an
-	  admin port command to retrieve the peer certificate. Submitted by
-	  Timo Teras.
-
-	* src/racoon/: admin.c, grabmyaddr.c, isakmp.c, misc.c, misc.h: Set
-	  sockets to be closed on exec to avoid potential file descriptor
-	  inheritance issues. Submitted by Timo Teras.
-
-	* src/racoon/: admin.c, grabmyaddr.c, ipsec_doi.c, isakmp.c,
-	  isakmp_cfg.c, isakmp_inf.c, privsep.c, remoteconf.c: Use utility
-	  functions to evaluate and manipulate network port values. No
-	  functional changes. Submitted by Timo Teras.
-
-	* src/racoon/: admin.c, racoonctl.c: Admin port code cleanup. No
-	  functional changes. Submitted by Timo Teras.
-
-	* src/racoon/pfkey.c: Correct a phase2 status event. Submitted by
-	  Timo Teras.
-
-2008-05-24  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/privsep.c: Coverity CID 5018: Fix double frees.
-
-2008-05-08  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* configure.ac: From Christian Hohnstaedt: allow out of tree
-	  building
-
-2008-04-30  Martin Husemann <martin@netbsd.org>
-
-	* netbsd-import.sh: Convert TNF licenses to new 2 clause variant
+	* src/racoon/: grabmyaddr.c, admin.c, ipsec_doi.c, isakmp.c,
+	  isakmp_cfg.c, isakmp_inf.c, remoteconf.c: Use utility functions
+	  to evaluate and manipulate network port values. No functional
+	  changes. Submitted by Timo Teras.
 
 2008-04-25  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/isakmp_inf.c: From Timo Teras: extract port numbers
 	  from SADB_X_EXT_NAT_T[SD]PORT if present in purge_ipsec_spi().
 
-2008-04-13  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/privsep.c: for symmetry set controllen the same way we
-	  set it on the receiving side.
-
-2008-04-02  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* src/racoon/: Makefile.am, sockmisc.c, sockmisc.h: fix Linux build
-
-2008-03-28  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/privsep.c: properly fix the variable stack allocation
-	  code.
-
-2008-03-28  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* src/racoon/privsep.c: Still from Cyrus Rahman: fix file
-	  descriptor leak introduced by previous commit.
-
-	* src/racoon/: Makefile.am, isakmp.c, isakmp_inf.c, privsep.c,
-	  privsep.h, sockmisc.c, doc/README.privsep: From Cyrus Rahman:
-	  Allow interface reconfiguration when running in privilege separation
-	  mode, document privilege separation
-
 2008-03-06  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/oakley.c: Generates a log if cert validation has been
 	  disabled by configuration
 
-2008-03-06  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* src/racoon/: privsep.c, session.c: From Cyrus Rahman
-	  <crahman@gmail.com> privilegied instance exit when unprivilegied one
-	  terminates. Save PID in real root, not in chroot
-
-2008-03-06  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/: admin.c, isakmp.c, isakmp_var.h, pfkey.c,
-	  racoonctl.8, racoonctl.c: Add the ability to initiate IPsec SA
-	  negotiations using the admin socket.  Submitted by Timo Teras.
-
-	* src/racoon/: admin.c, admin.h, evt.c, evt.h, handler.c,
-	  handler.h, isakmp.c, isakmp_agg.c, isakmp_base.c, isakmp_cfg.c,
-	  isakmp_ident.c, isakmp_inf.c, isakmp_var.h, isakmp_xauth.c,
-	  racoonctl.8, racoonctl.c, session.c: Refactor admin socket event
-	  protocol to be less error prone. Backwards compatibility is
-	  provided. Submitted by Timo Teras.
-
 2008-03-05  Matthew Grooms <mgrooms@shrew.net>
 
 	* src/racoon/cfparse.y: Properly initialize the unity network
 	  struct to prevent erroneous protocol and port info from being
 	  transmitted.
 
-	* src/racoon/: pfkey.c, pfkey.h, session.c: Reload SPD on SIGHUP or
-	  adminport reload. Also provide better handling for pfkey socket read
+	* src/racoon/pfkey.c: Provide better handling for pfkey socket read
 	  errors. Submitted by Timo Teras.
 
 2008-02-25  Emmanuel Dreyfus <manu@netbsd.org>
 
-	* src/racoon/ipsec_doi.c: From Brian Haley <brian.haley@hp.com>
+	* src/racoon/ipsec_doi.c: From Brian Haley <brian.haley@hp.com>:
 	  There's a cut/paste error in cmp_aproppair_i(), it's supposed to be
 	  checking spi_size but it's not.  I'm not sure this patch is correct,
 	  but what's there isn't either.
 
+	  Add fogotten entry in ChangeLog
+
 2008-02-22  Emmanuel Dreyfus <manu@netbsd.org>
 
-	* src/racoon/isakmp.c: Fix address length, from Brian Haley
-
-2008-02-10  S.P.Zeidler <spz@netbsd.org>
-
-	* src/racoon/ipsec_doi.c: closes PR bin/37644 did not meet violent
-	  opposition ( :) ) on ipsec-tools-devel
+	* src/racoon/isakmp.c: Fix bad address length computation, from
+	  Brian Haley.
 
 2008-01-11  Yvan Vanhullebus <vanhu@netasq.com>
 
@@ -1225,58 +208,12 @@
 	* src/racoon/: handler.c, handler.h: added an 'established' arg to
 	  getph1byaddr()
 
-2007-12-31  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/: policy.c, racoonctl.8, racoonctl.c: Add GRE protocol
-	  number to racoonctl. Correct id wildcard matching for transport
-	  mode. Submitted by Timo Teras.
-
-2007-12-12  Matthew Grooms <mgrooms@shrew.net>
-
-	* NEWS, src/racoon/isakmp_quick.c: Add corrections submitted in a
-	  follow up patch for the nat-t oa support.
-
-	* src/racoon/: handler.c, handler.h, isakmp_quick.c, pfkey.c: Add
-	  support for nat-t oa payload handling. Submitted by Timo Teras.
-
-2007-12-04  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/: ipsec_doi.c, ipsec_doi.h, isakmp_quick.c: Modify
-	  ipsecdoi_sockaddr2id() to obtain an id without specifying the exact
-	  prefix length. Correct a memory leak in phase2. Both submitted by
-	  Timo Teras.
-
-2007-12-01  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Fix typos. New sentence, new line.
-
 2007-11-29  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/Makefile.am: From Natanael Copa: fixed a race
 	  condition when building yacc stuff.
 
-2007-11-09  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/racoon/pfkey.c: From Arnaud Ebalard: Some sanity checking in
-	  pk_recv()
-
-	* src/racoon/policy.c: From Arnaud Ebalard: Better matching of SPD
-	  entries in getsp_r().
-
-	* src/racoon/isakmp_quick.c: From Arnaud Ebalard: Added some debug
-	  in get_proposal_r().
-
-2007-10-19  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* src/racoon/: isakmp_cfg.c, isakmp_unity.c, isakmp_unity.h,
-	  racoon.conf.5: Add SPLITNET_{INCLUDR_LOCAL}_CIDR to hook scripts
-
-2007-10-15  Yvan Vanhullebus <vanhu@netasq.com>
-
-	* src/libipsec/pfkey.c: Try to increase the buffer size of the
-	  pfkey socket, this may help things when we have a huge SPD
-
-2007-10-02  Yvan Vanhullebus <vanhu@netasq.com>
+2007-11-06  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/crypto_openssl.c: From Scott Lamb: include plog.h to
 	  work with the new plog macro.
@@ -1286,53 +223,34 @@
 
 	* src/racoon/: plog.c, plog.h: From Scott Lamb: new plog macro.
 
+2007-10-15  Yvan Vanhullebus <vanhu@netasq.com>
+
+	* src/libipsec/pfkey.c: Try to increase the buffer size of the
+	  pfkey socket, this may help things when we have a huge SPD
+
 2007-09-19  Matthew Grooms <mgrooms@shrew.net>
 
-	* src/racoon/isakmp.c: Set REUSE option on sockets to prevent
-	  failures associated with closing and immediately re-opening.
-	  Submitted by Gabriel Somlo.
-
-	* src/racoon/isakmp_unity.c: Prevent duplicate entries in splitnet
-	  list. Submitted by Gabriel Somlo.
-
-2007-09-13  Matthew Grooms <mgrooms@shrew.net>
-
 	* configure.ac: Fix autoconf check for selinux support. Submitted
 	  by Joy Latten.
 
-2007-09-12  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/: cfparse.y, cftoken.l, handler.c, isakmp_quick.c,
-	  pfkey.c, racoon.conf.5, sainfo.c, sainfo.h: Implement clientaddr
-	  sainfo remote id option and refine the sainfo man page syntax.
-
-2007-09-05  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/sainfo.c: Sort sainfo sections on insert and improve
-	  matching logic.
-
 2007-09-03  Matthew Grooms <mgrooms@shrew.net>
 
 	* src/racoon/: cftoken.l, racoon.conf.5: Correct the syntax for
 	  wins4 in the man page and add nbns4 as an alias. Pointed out by
 	  Claas Langbehn.
 
+2007-08-09  tag ipsec-tools-0_7
+
+2007-08-09  Matthew Grooms <mgrooms@shrew.net>
+
+	* NEWS, configure.ac: Prepare for 0.7 release tag.
+
 2007-08-07  Emmanuel Dreyfus <manu@netbsd.org>
 
-	* src/racoon/isakmp_xauth.c: src/racoon/isakmp_xauth.c: Don't mix
-	  up RADIUS authentication and authorization ports. Allow
-	  interoperability with freeradius
+	* src/racoon/isakmp_xauth.c: Don't mix up RADIUS authentication and
+	  authorization ports. Allow interoperability with freeradius
 
-2007-07-24  Matthew Grooms <mgrooms@shrew.net>
-
-	* NEWS: Update NEWS file with additional 0.7 improvements.
-
-2007-07-18  Matthew Grooms <mgrooms@shrew.net>
-
-	* src/racoon/racoon.conf.5: Various racoon configuration manpage
-	  updates.
-
-2007-07-18  Yvan Vanhullebus <vanhu@netasq.com>
+2007-08-01  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* configure.ac, src/libipsec/ipsec_dump_policy.c,
 	  src/libipsec/ipsec_get_policylen.c,
@@ -1351,50 +269,58 @@
 	  src/setkey/token.l: use a single PATH_IPSEC_H to fix some
 	  path_to_ipsec.h issues
 
+2007-07-24  Matthew Grooms <mgrooms@shrew.net>
+
+	* NEWS: Update NEWS file with additional 0.7 improvements.
+
+2007-07-18  Matthew Grooms <mgrooms@shrew.net>
+
+	* src/racoon/racoon.conf.5: Various racoon configuration manpage
+	  updates.
+
 2007-07-16  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/grabmyaddr.c: fixed a socket leak
 
-	* src/racoon/proposal.c: indentation
+2007-06-12  tag ipsec-tools-0_7-RC1
+
+2007-06-12  tag ipsec-tools-0_7-rc1
+
+2007-06-12  Emmanuel Dreyfus <manu@netbsd.org>
+
+	* configure.ac: ipsec-tools used to use tags in lower case
+
+2007-06-12  Yvan Vanhullebus <vanhu@netasq.com>
+
+	* configure.ac: 0.7-RC1
 
 2007-06-07  Emmanuel Dreyfus <manu@netbsd.org>
 
+	* src/racoon/: main.c, policy.h, security.c: From Joy Latten
+	  <latten@austin.ibm.com> Fix file descriptor shortage when using
+	  labeled IPsec.
+
 	* src/racoon/isakmp_cfg.c: From Paul Winder
-	  <Paul.Winder@tadpole.com>: Fix ignored INTERNAL_DNS4_LIST
+	  <Paul.Winder@tadpole.com> Fix ignored INTERNAL_DNS4_LIST
 
 2007-06-06  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/: eaytest.c, var.h: From Rong-En Fan: fix compilation
 	  with gcc 4.2
 
+2007-06-06  Emmanuel Dreyfus <manu@netbsd.org>
+
+	* src/racoon/kmpstat.c: From Jianli Liu <jlliu@nortel.com>: Use the
+	  specified socket path instead of the default location
+
+2007-06-06  Yvan Vanhullebus <vanhu@netasq.com>
+
 	* src/racoon/session.c: From Jianli Liu: speed up interfaces update
 	  when they change.
 
 	* src/racoon/handler.c: ignore obsolete lifebyte when validating
 	  reloaded configuration
 
-2007-05-31  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* src/racoon/: main.c, policy.h, security.c: From Joy Latten
-	  <latten@austin.ibm.com> Fix file descriptor shortage when using
-	  labeled IPsec.
-
-2007-05-30  Emmanuel Dreyfus <manu@netbsd.org>
-
-	* src/racoon/kmpstat.c: From Jianli Liu <jlliu@nortel.com>: In
-	  racoonctl, use the specified socket path instead of the default
-	  location
-
-2007-05-16  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/cfparse.y: coverity CID 4168: yyerror() does not
-	  return, so we proceed to de-reference NULL. Make it return -1
-	  instead like in other places.
-
-	* src/racoon/cfparse.y: coverity CID 4170: yyerror() does not
-	  return, so we proceed to de-reference NULL. Make it return -1
-	  instead like in other places.
-
 2007-05-04  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/handler.c: search a ph1 by address if iph2->ph1 is
@@ -1419,17 +345,18 @@
 	* src/racoon/oakley.c: dumps peer's ID and peer's certificate
 	  subject /subjectaltname if they don't match
 
+2007-03-29  tag ipsec-tools-0_7-beta3
+
+2007-03-29  Emmanuel Dreyfus <manu@netbsd.org>
+
+	* configure.ac: Bump to 0.7beta3
+
 2007-03-26  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/isakmp_inf.c: Store the DPD main scheduler in ph1
 	  handler, to be able to cancel it when removing the handler, and some
 	  minor cleanups in DPD code
 
-2007-03-24  Christos Zoulas <christos@netbsd.org>
-
-	* src/racoon/isakmp_xauth.c: PR/36069: Huang Yushuo: racoon can't
-	  work with pam_group Set RUSER.
-
 2007-03-23  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/: ipsec_doi.c, security.c: From Joy Latten: fix a
@@ -1462,7 +389,13 @@
 	* src/racoon/isakmp.c: Consider a negociation timeout when
 	  retry_counter is <=0 instead of < 0
 
-2007-02-28  Matthew Grooms <mgrooms@shrew.net>
+2007-03-06  tag ipsec-tools-0_7-beta2
+
+2007-03-06  Emmanuel Dreyfus <manu@netbsd.org>
+
+	* configure.ac: Bump to 0.7beta2
+
+2007-03-01  Matthew Grooms <mgrooms@shrew.net>
 
 	* src/racoon/ipsec_doi.c: Add logic to allow ip address ids to be
 	  matched to ip subnet ids when appropriate.
@@ -1490,6 +423,12 @@
 
 	* src/racoon/isakmp.c: Removed a debug printf....
 
+2007-02-16  tag ipsec-tools-0_7-beta1
+
+2007-02-16  Emmanuel Dreyfus <manu@netbsd.org>
+
+	* configure.ac: Bump to 0.7beta1
+
 2007-02-16  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/ipsec_doi.c: From Olivier Warin: Fix a %zu in a
@@ -1497,7 +436,7 @@
 
 2007-02-15  Emmanuel Dreyfus <manu@netbsd.org>
 
-	* src/racoon/security.c: Missing SELinux file
+	* src/racoon/security.c: Missing file for SELinux
 
 	* configure.ac: Missing stuff for SELinux
 
@@ -1521,20 +460,6 @@
 	  deleted from payload instead of just deleting the ISAKMP SA used to
 	  protect the informational exchange.
 
-2006-12-26  Arnaud Lacombe <alc@netbsd.org>
-
-	* src/racoon/ipsec_doi.c: CID-4167: check for 'iph1->approval !=
-	  NULL'
-
-2006-12-23  Thomas Klausner <wiz@netbsd.org>
-
-	* src/racoon/racoon.conf.5: Use even more macros.
-
-	* src/racoon/racoon.conf.5: Use more macros.
-
-	* src/racoon/racoon.conf.5: Serial comma, and bump date for
-	  previous.
-
 2006-12-18  Yvan Vanhullebus <vanhu@netasq.com>
 
 	* src/racoon/crypto_openssl.c: From Joy Latten: fix a memory leak
diff --git a/NEWS b/NEWS
index 6193c65..29ce752 100644
--- a/NEWS
+++ b/NEWS
@@ -1,38 +1,36 @@
 Version history:
 ----------------
-0.8	- 18 March 2011
-	o Fix authentication method ambiguity with kerberos and xauth
-	o RFC2253 compliant escaping of asn1dn identifiers (Cyrus Rahman)
-	o Local address code rewrite to speed things up
-	o Improved MIPv6 support (Arnaud Ebalard)
-	o ISAKMP SA (phase1) rekeying
-	o Improved scheduler (faster algorithm, support monotonic clock)
-	o Handle RESPONDER-LIFETIME in quick mode
-	o Handle INITIAL-CONTACT in from main mode too
-	o Rewritten event handling framework for admin port
-	o Ability to initiate IPsec SA through admin port
-	o NAT-T Original Address handling (transport mode NAT-T support)
-	o clean NAT-T - PFkey support
-	o support for multiple anonymous remoteconfs
-	o Remove various obsolete configuration options
-	o A lot of other bug fixes, performance improvements and clean ups
 
-0.7.1	- 23 July 2008
+0.7.3 - 23 August 2009
+	o Fix a remote crash and a memory leak
+	o Fixed a NAT-T flag check
+	o Some code cleanups/compilation fixes with recent gcc
+
+0.7.2 - 22 April 2009
+	o Fix a remote crash in fragmentation code
+	o Phase2 message identities are phase1 specific (Vista compatibility=
+	o Autogenerate ChangeLog from cvs metadata
+	o Fix mode config pool resizing
+	o NAT-T fixes related to purging of IPsec SA:s and retransmission
+	o Remove phase1 handler immediately if first exchange is bad
+	o A bunch of memory leak and possible memory corruptions (triggerable
+	  by bad configuration or startup parameters)
+
+0.7.1 - 23 July 2008
 	o Fixes a memory leak when invalid proposal received
 	o Some fixes in DPD
 	o do not set default gss id if xauth is used
 	o fixed hybrid enabled builds
 	o fixed compilation on FreeBSD8
 	o cleanup in network port value manipulation
-	o Gets ports from SADB_X_EXT_NAT_T_[SD]PORT if present in
-	  purge_ipsec_spi()
-	o Generates a log if cert validation has been disabled by
-	  configuration
+	o gets ports from SADB_X_EXT_NAT_T_[SD]PORT if present in purge_ipsec_spi()
+	o Generates a log if cert validation has been disabled by configuration
 	o better handling for pfkey socket read errors
 	o Fixes in yacc / bison stuff
 	o new plog() macro (reduced CPU usage when logging is disabled)
-	o Try to work better with huge SPD/SAD
+	o Try to works better with huge SPD/SAD
 	o Corrected modecfg option syntax
+	o Many other various fixes...
 
 0.7	- 09 August 2007
 	o Xauth with pre-shared key PSK
@@ -65,7 +63,7 @@
 	o ESP fragmentation in tunnel mode can be tunned (NetBSD only)
 	o racoon admin interface is exported (header and library) to 
 	  help building control programs for racoon (think GUI)
-	o Fixed single DES support; single DES users MUST UPGRADE.
+ 	o Fixed single DES support; single DES users MUST UPGRADE.
 
 0.5	- 10 April 2005
 	o Rewritten buildsystem. Now completely autoconfed, automaked,
@@ -93,7 +91,7 @@
 	o All source files now have 3-clause BSD license.
 
 0.3	- 14 April 2004
-	o Fixed setkey to handle multiline commands again.
+        o Fixed setkey to handle multiline commands again.
 	o Added command 'exit' to setkey.
 	o Fixed racoon to only Warn if no CRL was found.
 	o Improved testsuite.
diff --git a/README b/README
index 9623997..2e4f90a 100644
--- a/README
+++ b/README
@@ -11,27 +11,20 @@
 IPsec-tools were ported to Linux from the KAME project 
 (http://www.kame.net) by Derek Atkins  <derek@ihtfp.com>.
 
-Currently the package is actively maintained and developed by: 
-	Emmanuel Dreyfus <manu@netbsd.org>
-	VANHULLEBUS Yvan <vanhu@free.fr>
-	Matthew Grooms <mgrooms@shrew.net>
-	Timo Teräs <timo.teras@iki.fi>
+Currently the package is actively maintained and developed 
+by Michal Ludvig <mludvig@suse.cz>, Aidas Kasparas <a.kasparas@gmc.lt>
+Emmanuel Dreyfus <manu@netbsd.org>, VANHULLEBUS Yvan <vanhu@zeninc.net>,
+and Fred Senault <fred.letter@lacave.net>.
 
 Sources can be found at the IPsec-Tools home page at:
 	http://ipsec-tools.sourceforge.net/
 
-And CVS repository is hosted at NetBSD tree:
-	cvs -danoncvs@anoncvs.netbsd.org:/cvsroot co ipsec-tools
-
-Bug reports and project wiki is located at:
-	https://trac.ipsec-tools.net/
-
 Please report any problems to the mailing list:
 	ipsec-tools-devel@lists.sourceforge.net
 	ipsec-tools-users@lists.sourceforge.net
 
 You can also browse the list archive:
-	http://sf.net/mailarchive/forum.php?forum_name=ipsec-tools-devel
+	http://sourceforge.net/mailarchive/forum.php?forum_id=32000
 
 Credits:
 	IHTFP Consulting, see http://www.ihtfp.com/
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
index 9af3ed7..6ec7936 100644
--- a/ThirdPartyProject.prop
+++ b/ThirdPartyProject.prop
@@ -1,7 +1,7 @@
-# Copyright 2011 Google Inc. All Rights Reserved.
-#Tue Jul  5 19:05:36 PDT 2011
-currentVersion=0.8.0
-version=0.8.0
+# Copyright 2010 Google Inc. All Rights Reserved.
+#Fri Jul 16 10:03:09 PDT 2010
+currentVersion=0.7.3
+version=0.7.3 (unreleased)
 isNative=true
 name=ipsec-tools
 keywords=ipsec-tools
diff --git a/main.c b/main.c
index 34b474f..2976ecc 100644
--- a/main.c
+++ b/main.c
@@ -22,7 +22,6 @@
 
 #include "config.h"
 #include "gcmalloc.h"
-#include "session.h"
 #include "schedule.h"
 #include "plog.h"
 
@@ -125,15 +124,12 @@
 
 extern void setup(int argc, char **argv);
 
-char *pname;
-
-static int monitor_count;
-static struct {
-    int (*callback)(void *ctx, int fd);
-    void *ctx;
-} monitors[10];
+static int monitors;
+static void (*callbacks[10])(int fd);
 static struct pollfd pollfds[10];
 
+char *pname;
+
 static void terminate(int signal)
 {
     exit(1);
@@ -144,17 +140,29 @@
     do_plog(LLV_INFO, "Bye\n");
 }
 
+void monitor_fd(int fd, void (*callback)(int))
+{
+    if (fd < 0 || monitors == 10) {
+        do_plog(LLV_ERROR, "Cannot monitor fd");
+        exit(1);
+    }
+    callbacks[monitors] = callback;
+    pollfds[monitors].fd = fd;
+    pollfds[monitors].events = callback ? POLLIN : 0;
+    ++monitors;
+}
+
 int main(int argc, char **argv)
 {
 #ifdef ANDROID_CHANGES
     int control = android_get_control_and_arguments(&argc, &argv);
     if (control != -1) {
         pname = "%p";
-        monitor_fd(control, NULL, NULL, 0);
+        monitor_fd(control, NULL);
     }
 #endif
 
-    do_plog(LLV_INFO, "ipsec-tools 0.8.0 (http://ipsec-tools.sf.net)\n");
+    do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n");
 
     signal(SIGHUP, terminate);
     signal(SIGINT, terminate);
@@ -173,15 +181,15 @@
         struct timeval *tv = schedular();
         int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1;
 
-        if (poll(pollfds, monitor_count, timeout) > 0) {
+        if (poll(pollfds, monitors, timeout) > 0) {
             int i;
-            for (i = 0; i < monitor_count; ++i) {
+            for (i = 0; i < monitors; ++i) {
                 if (pollfds[i].revents & POLLHUP) {
                     do_plog(LLV_ERROR, "Connection is closed\n", pollfds[i].fd);
                     exit(1);
                 }
                 if (pollfds[i].revents & POLLIN) {
-                    monitors[i].callback(monitors[i].ctx, pollfds[i].fd);
+                    callbacks[i](pollfds[i].fd);
                 }
             }
         }
@@ -189,26 +197,6 @@
     return 0;
 }
 
-/* session.h */
-
-void monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority)
-{
-    if (fd < 0 || monitor_count == 10) {
-        do_plog(LLV_ERROR, "Cannot monitor fd");
-        exit(1);
-    }
-    monitors[monitor_count].callback = callback;
-    monitors[monitor_count].ctx = ctx;
-    pollfds[monitor_count].fd = fd;
-    pollfds[monitor_count].events = callback ? POLLIN : 0;
-    ++monitor_count;
-}
-
-void unmonitor_fd(int fd)
-{
-    exit(1);
-}
-
 /* plog.h */
 
 void do_plog(int level, char *format, ...)
diff --git a/setup.c b/setup.c
index ab494a8..d8861d1 100644
--- a/setup.c
+++ b/setup.c
@@ -58,12 +58,9 @@
 static struct sainfo sainfo;
 static char *pre_shared_key;
 
-static char *interface;
 static struct sockaddr *targets[2];
-static struct {
-    struct sockaddr *addr;
-    int fd;
-} sources[2];
+static struct sockaddr *source;
+static struct myaddrs myaddrs[2];
 
 struct localconf *lcconf = &localconf;
 int f_local = 0;
@@ -87,7 +84,7 @@
     }
 }
 
-static void set_globals(char *interfaze, char *server)
+static void set_globals(char *server)
 {
     struct addrinfo hints = {
         .ai_flags = AI_NUMERICSERV,
@@ -110,18 +107,26 @@
     targets[0] = dupsaddr(info->ai_addr);
     freeaddrinfo(info);
 
-    interface = interfaze;
-    sources[0].addr = getlocaladdr(targets[0]);
-    if (!sources[0].addr) {
+    source = getlocaladdr(targets[0]);
+    if (!source) {
         do_plog(LLV_ERROR, "Cannot get local address\n");
         exit(1);
     }
     set_port(targets[0], 0);
-    set_port(sources[0].addr, 0);
-    sources[0].fd = -1;
-    sources[1].addr = dupsaddr(sources[0].addr);
-    sources[1].fd = -1;
+    set_port(source, 0);
 
+    myaddrs[0].addr = dupsaddr(source);
+    set_port(myaddrs[0].addr, PORT_ISAKMP);
+    myaddrs[0].sock = -1;
+#ifdef ENABLE_NATT
+    myaddrs[0].next = &myaddrs[1];
+    myaddrs[1].addr = dupsaddr(myaddrs[0].addr);
+    set_port(myaddrs[1].addr, PORT_ISAKMP_NATT);
+    myaddrs[1].sock = -1;
+    myaddrs[1].udp_encap = 1;
+#endif
+
+    localconf.myaddrs = &myaddrs[0];
     localconf.port_isakmp = PORT_ISAKMP;
     localconf.port_isakmp_natt = PORT_ISAKMP_NATT;
     localconf.default_af = AF_INET;
@@ -156,8 +161,7 @@
 {
     if (address) {
         struct sockaddr *addr = PFKEY_ADDR_SADDR(address);
-        return cmpsaddr(addr, targets[0]) < CMPSADDR_MISMATCH ||
-                cmpsaddr(addr, targets[1]) < CMPSADDR_MISMATCH;
+        return !cmpsaddrwop(addr, targets[0]) || !cmpsaddrwop(addr, targets[1]);
     }
     return 0;
 }
@@ -303,6 +307,7 @@
     p->hashtype = hash;
     p->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
     p->vendorid = VENDORID_UNKNOWN;
+    p->rmconf = remoteconf;
 
     if (!remoteconf->proposal) {
       p->trns_no = 1;
@@ -322,6 +327,7 @@
     vchar_t *vchar = string ? vmalloc(strlen(string) + 1) : NULL;
     if (vchar) {
         memcpy(vchar->v, string, vchar->l);
+        vchar->l -= 1;
     }
     return vchar;
 }
@@ -332,7 +338,6 @@
     pre_shared_key = key;
     if (identifier[0]) {
         remoteconf->idv = strtovchar(identifier);
-        remoteconf->idv->l -= 1;
         remoteconf->etypes->type = ISAKMP_ETYPE_AGG;
 
         remoteconf->idvtype = IDTYPE_KEYID;
@@ -345,20 +350,6 @@
     }
 }
 
-static vchar_t *get_certificate(char *type, char *file)
-{
-    char path[PATH_MAX + 1];
-    vchar_t *certificate = NULL;
-
-    getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file);
-    certificate = eay_get_x509cert(path);
-    if (!certificate) {
-        do_plog(LLV_ERROR, "Cannot load %s certificate\n", type);
-        exit(1);
-    }
-    return certificate;
-}
-
 static void set_certificates(struct remoteconf *remoteconf,
         char *user_private_key, char *user_certificate,
         char *ca_certificate, char *server_certificate)
@@ -367,16 +358,15 @@
     remoteconf->mycertfile = user_certificate;
     if (user_certificate) {
         remoteconf->idvtype = IDTYPE_ASN1DN;
-        remoteconf->mycert = get_certificate("user", user_certificate);
     }
     if (!ca_certificate[0]) {
         remoteconf->verify_cert = FALSE;
     } else {
         remoteconf->cacertfile = ca_certificate;
-        remoteconf->cacert = get_certificate("CA", ca_certificate);
     }
     if (server_certificate[0]) {
-        remoteconf->peerscert = get_certificate("server", server_certificate);
+        remoteconf->peerscertfile = server_certificate;
+        remoteconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
     }
 }
 
@@ -387,7 +377,9 @@
 {
     struct xauth_rmconf *xauth = racoon_calloc(1, sizeof(struct xauth_rmconf));
     xauth->login = strtovchar(username);
+    xauth->login->l += 1;
     xauth->pass = strtovchar(password);
+    xauth->pass->l += 1;
     remoteconf->xauth = xauth;
     remoteconf->mode_cfg = TRUE;
     remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar(phase1_up);
@@ -396,13 +388,24 @@
 
 #endif
 
+extern void monitor_fd(int fd, void (*callback)(int));
+
+void add_isakmp_handler(int fd, const char *interface)
+{
+    if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
+            interface, strlen(interface))) {
+        do_plog(LLV_WARNING, "Cannot bind socket to %s\n", interface);
+    }
+    monitor_fd(fd, (void *)isakmp_handler);
+}
+
 void setup(int argc, char **argv)
 {
     struct remoteconf *remoteconf = NULL;
     int auth;
 
     if (argc > 2) {
-        set_globals(argv[1], argv[2]);
+        set_globals(argv[2]);
 
         /* Initialize everything else. */
         eay_init();
@@ -413,7 +416,10 @@
         if (pfkey_init() < 0 || isakmp_init() < 0) {
             exit(1);
         }
+        monitor_fd(localconf.sock_pfkey, (void *)pfkey_handler);
+        add_isakmp_handler(myaddrs[0].sock, argv[1]);
 #ifdef ENABLE_NATT
+        add_isakmp_handler(myaddrs[1].sock, argv[1]);
         natt_keepalive_init();
 #endif
 
@@ -424,6 +430,7 @@
         remoteconf->idvtype = IDTYPE_ADDRESS;
         remoteconf->ike_frag = TRUE;
         remoteconf->pcheck_level = PROP_CHECK_CLAIM;
+        remoteconf->certtype = ISAKMP_CERT_X509SIGN;
         remoteconf->gen_policy = TRUE;
         remoteconf->nat_traversal = TRUE;
         remoteconf->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
@@ -431,7 +438,6 @@
         remoteconf->script[SCRIPT_PHASE1_DOWN] = strtovchar("");
         oakley_setdhgroup(remoteconf->dh_group, &remoteconf->dhgrp);
         remoteconf->remote = dupsaddr(targets[0]);
-        set_port(remoteconf->remote, localconf.port_isakmp);
     }
 
     /* Set authentication method and credentials. */
@@ -440,13 +446,13 @@
         auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY;
 
         set_port(targets[0], atoi(argv[6]));
-        spdadd(sources[0].addr, targets[0], IPPROTO_UDP, NULL, NULL);
+        spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
     } else if (argc == 9 && !strcmp(argv[3], "udprsa")) {
         set_certificates(remoteconf, argv[4], argv[5], argv[6], argv[7]);
         auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG;
 
         set_port(targets[0], atoi(argv[8]));
-        spdadd(sources[0].addr, targets[0], IPPROTO_UDP, NULL, NULL);
+        spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
 #ifdef ENABLE_HYBRID
     } else if (argc == 10 && !strcmp(argv[3], "xauthpsk")) {
         set_pre_shared_key(remoteconf, argv[4], argv[5]);
@@ -500,24 +506,9 @@
     /* Install remote configuration. */
     insrmconf(remoteconf);
 
-    /* Create ISAKMP sockets. */
-    set_port(sources[0].addr, localconf.port_isakmp);
-    sources[0].fd = isakmp_open(sources[0].addr, FALSE);
-    if (sources[0].fd == -1) {
-        do_plog(LLV_ERROR, "Cannot create ISAKMP socket\n");
-        exit(1);
-    }
-#ifdef ENABLE_NATT
-    set_port(sources[1].addr, localconf.port_isakmp_natt);
-    sources[1].fd = isakmp_open(sources[1].addr, TRUE);
-    if (sources[1].fd == -1) {
-        do_plog(LLV_WARNING, "Cannot create ISAKMP socket for NAT-T\n");
-    }
-#endif
-
     /* Start phase 1 negotiation for xauth. */
     if (remoteconf->xauth) {
-        isakmp_ph1begin_i(remoteconf, remoteconf->remote, sources[0].addr);
+        isakmp_ph1begin_i(remoteconf, remoteconf->remote, source);
     }
 }
 
@@ -552,35 +543,29 @@
     return 0;
 }
 
-int myaddr_getfd(struct sockaddr *addr)
+int getsockmyaddr(struct sockaddr *addr)
 {
 #ifdef ENABLE_NATT
-    if (sources[1].fd != -1 &&
-            cmpsaddr(addr, sources[1].addr) == CMPSADDR_MATCH) {
-        return sources[1].fd;
+    if (!cmpsaddrstrict(addr, myaddrs[1].addr)) {
+        return myaddrs[1].sock;
     }
 #endif
-    if (cmpsaddr(addr, sources[0].addr) < CMPSADDR_MISMATCH) {
-        return sources[0].fd;
+    if (!cmpsaddrwop(addr, myaddrs[0].addr)) {
+        return myaddrs[0].sock;
     }
     return -1;
 }
 
 /* privsep.h */
 
-int privsep_socket(int domain, int type, int protocol)
+int privsep_pfkey_open()
 {
-    int fd = socket(domain, type, protocol);
-    if ((domain == AF_INET || domain == AF_INET6) && setsockopt(
-            fd, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface))) {
-        do_plog(LLV_WARNING, "Cannot bind socket to %s\n", interface);
-    }
-    return fd;
+    return pfkey_open();
 }
 
-int privsep_bind(int fd, const struct sockaddr *addr, socklen_t addrlen)
+void privsep_pfkey_close(int key)
 {
-    return bind(fd, addr, addrlen);
+    pfkey_close(key);
 }
 
 vchar_t *privsep_eay_get_pkcs1privkey(char *file)
@@ -657,15 +642,10 @@
     return 0;
 }
 
-void close_on_exec(int fd)
-{
-    fcntl(fd, F_SETFD, FD_CLOEXEC);
-}
-
 /* sainfo.h */
 
 struct sainfo *getsainfo(const vchar_t *src, const vchar_t *dst,
-        const vchar_t *peer, const vchar_t *client, uint32_t remoteid)
+        const vchar_t *peer, int remoteid)
 {
     return &sainfo;
 }
diff --git a/src/include-glibc/Makefile.in b/src/include-glibc/Makefile.in
index d92fdf6..842728e 100644
--- a/src/include-glibc/Makefile.in
+++ b/src/include-glibc/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -16,9 +15,8 @@
 @SET_MAKE@
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
@@ -43,7 +41,6 @@
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
 DIST_SOURCES =
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -61,18 +58,23 @@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
 CRYPTOBJS = @CRYPTOBJS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
+ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 EXTRA_CRYPTO = @EXTRA_CRYPTO@
-FGREP = @FGREP@
+F77 = @F77@
+FFLAGS = @FFLAGS@
 FRAG_OBJS = @FRAG_OBJS@
 GLIBC_BUGS = @GLIBC_BUGS@
 GREP = @GREP@
@@ -86,7 +88,6 @@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 KERNEL_INCLUDE = @KERNEL_INCLUDE@
 KRB5_CONFIG = @KRB5_CONFIG@
-LD = @LD@
 LDFLAGS = @LDFLAGS@
 LEX = @LEX@
 LEXLIB = @LEXLIB@
@@ -94,24 +95,18 @@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
 NATT_OBJS = @NATT_OBJS@
-NM = @NM@
 NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
 PACKAGE_STRING = @PACKAGE_STRING@
 PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
@@ -129,7 +124,8 @@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -161,7 +157,6 @@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -174,7 +169,6 @@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 EXTRA_DIST = \
@@ -191,14 +185,14 @@
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/include-glibc/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign src/include-glibc/Makefile
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/include-glibc/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  src/include-glibc/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -216,7 +210,6 @@
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
 
 mostlyclean-libtool:
 	-rm -f *.lo
@@ -246,17 +239,13 @@
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
 	  if test -d $$d/$$file; then \
 	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
 	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
 	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
 	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
 	    || exit 1; \
 	  fi; \
 	done
@@ -284,7 +273,6 @@
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
 	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
 
 maintainer-clean-generic:
@@ -304,8 +292,6 @@
 
 html: html-am
 
-html-am:
-
 info: info-am
 
 info-am:
@@ -314,28 +300,18 @@
 
 install-dvi: install-dvi-am
 
-install-dvi-am:
-
 install-exec-am:
 
 install-html: install-html-am
 
-install-html-am:
-
 install-info: install-info-am
 
-install-info-am:
-
 install-man:
 
 install-pdf: install-pdf-am
 
-install-pdf-am:
-
 install-ps: install-ps-am
 
-install-ps-am:
-
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
@@ -375,7 +351,6 @@
 	touch .includes
 
 all: .includes
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/src/libipsec/Makefile.in b/src/libipsec/Makefile.in
index cd0993b..748877a 100644
--- a/src/libipsec/Makefile.in
+++ b/src/libipsec/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -18,9 +17,8 @@
 
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
@@ -47,30 +45,15 @@
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
     *) f=$$p;; \
   esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \
 	"$(DESTDIR)$(libipsecdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libipsec_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
@@ -84,7 +67,6 @@
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
-am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -106,6 +88,7 @@
 man3dir = $(mandir)/man3
 NROFF = nroff
 MANS = $(man3_MANS)
+libipsecHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(libipsec_HEADERS) $(noinst_HEADERS)
 ETAGS = etags
 CTAGS = ctags
@@ -124,18 +107,23 @@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
 CRYPTOBJS = @CRYPTOBJS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
+ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 EXTRA_CRYPTO = @EXTRA_CRYPTO@
-FGREP = @FGREP@
+F77 = @F77@
+FFLAGS = @FFLAGS@
 FRAG_OBJS = @FRAG_OBJS@
 GLIBC_BUGS = @GLIBC_BUGS@
 GREP = @GREP@
@@ -149,7 +137,6 @@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 KERNEL_INCLUDE = @KERNEL_INCLUDE@
 KRB5_CONFIG = @KRB5_CONFIG@
-LD = @LD@
 LDFLAGS = @LDFLAGS@
 LEX = @LEX@
 LEXLIB = @LEXLIB@
@@ -157,24 +144,18 @@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
 NATT_OBJS = @NATT_OBJS@
-NM = @NM@
 NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
 PACKAGE_STRING = @PACKAGE_STRING@
 PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
@@ -192,7 +173,8 @@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -224,7 +206,6 @@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -237,7 +218,6 @@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
@@ -282,14 +262,14 @@
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libipsec/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign src/libipsec/Makefile
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/libipsec/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  src/libipsec/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -307,28 +287,23 @@
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
 	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-	list2=; for p in $$list; do \
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
 	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
+	    f=$(am__strip_dir) \
+	    echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+	    $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
 	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-	}
+	done
 
 uninstall-libLTLIBRARIES:
 	@$(NORMAL_UNINSTALL)
-	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  p=$(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
 	done
 
 clean-libLTLIBRARIES:
@@ -364,21 +339,21 @@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(COMPILE) -c $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
@@ -394,74 +369,82 @@
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-man3: $(man3_MANS)
+install-man3: $(man3_MANS) $(man_MANS)
 	@$(NORMAL_INSTALL)
 	test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
-	@list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \
-	{ for i in $$list; do echo "$$i"; done; \
-	} | while read p; do \
-	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; echo "$$p"; \
-	done | \
-	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
-	sed 'N;N;s,\n, ,g' | { \
-	list=; while read file base inst; do \
-	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
-	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
-	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
-	  fi; \
+	@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.3*) list="$$list $$i" ;; \
+	  esac; \
 	done; \
-	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
-	while read files; do \
-	  test -z "$$files" || { \
-	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
-	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
-	done; }
-
+	for i in $$list; do \
+	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+	  else file=$$i; fi; \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    3*) ;; \
+	    *) ext='3' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+	  $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
+	done
 uninstall-man3:
 	@$(NORMAL_UNINSTALL)
-	@list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \
-	files=`{ for i in $$list; do echo "$$i"; done; \
-	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
-	test -z "$$files" || { \
-	  echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
-	  cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
+	@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.3*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    3*) ;; \
+	    *) ext='3' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
+	  rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
+	done
 install-libipsecHEADERS: $(libipsec_HEADERS)
 	@$(NORMAL_INSTALL)
 	test -z "$(libipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(libipsecdir)"
-	@list='$(libipsec_HEADERS)'; test -n "$(libipsecdir)" || list=; \
-	for p in $$list; do \
+	@list='$(libipsec_HEADERS)'; for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libipsecdir)'"; \
-	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libipsecdir)" || exit $$?; \
+	  f=$(am__strip_dir) \
+	  echo " $(libipsecHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libipsecdir)/$$f'"; \
+	  $(libipsecHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libipsecdir)/$$f"; \
 	done
 
 uninstall-libipsecHEADERS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(libipsec_HEADERS)'; test -n "$(libipsecdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libipsecdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(libipsecdir)" && rm -f $$files
+	@list='$(libipsec_HEADERS)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(libipsecdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(libipsecdir)/$$f"; \
+	done
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
 	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
 TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
-	set x; \
+	tags=; \
 	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
@@ -469,52 +452,34 @@
 	  done | \
 	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
 	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
 	fi
 ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
+	tags=; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
 	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
 	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	test -z "$(CTAGS_ARGS)$$unique" \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
+	     $$tags $$unique
 
 GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
-	@list='$(MANS)'; if test -n "$$list"; then \
-	  list=`for p in $$list; do \
-	    if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
-	    if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
-	  if test -n "$$list" && \
-	    grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
-	    echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
-	    grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/         /' >&2; \
-	    echo "       to fix them, install help2man, remove and regenerate the man pages;" >&2; \
-	    echo "       typically \`make maintainer-clean' will remove them" >&2; \
-	    exit 1; \
-	  else :; fi; \
-	else :; fi
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	list='$(DISTFILES)'; \
@@ -530,17 +495,13 @@
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
 	  if test -d $$d/$$file; then \
 	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
 	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
 	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
 	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
 	    || exit 1; \
 	  fi; \
 	done
@@ -573,7 +534,6 @@
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -599,8 +559,6 @@
 
 html: html-am
 
-html-am:
-
 info: info-am
 
 info-am:
@@ -609,28 +567,18 @@
 
 install-dvi: install-dvi-am
 
-install-dvi-am:
-
 install-exec-am: install-libLTLIBRARIES
 
 install-html: install-html-am
 
-install-html-am:
-
 install-info: install-info-am
 
-install-info-am:
-
 install-man: install-man3
 
 install-pdf: install-pdf-am
 
-install-pdf-am:
-
 install-ps: install-ps-am
 
-install-ps-am:
-
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
@@ -656,7 +604,7 @@
 
 uninstall-man: uninstall-man3
 
-.MAKE: all check install install-am install-strip
+.MAKE: install-am install-strip
 
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
 	clean-libLTLIBRARIES clean-libtool ctags distclean \
@@ -674,7 +622,6 @@
 	uninstall-am uninstall-libLTLIBRARIES \
 	uninstall-libipsecHEADERS uninstall-man uninstall-man3
 
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/src/libipsec/ipsec_dump_policy.c b/src/libipsec/ipsec_dump_policy.c
index 4d0eb77..bdadb47 100644
--- a/src/libipsec/ipsec_dump_policy.c
+++ b/src/libipsec/ipsec_dump_policy.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_dump_policy.c,v 1.9 2010/12/03 15:01:11 tteras Exp $	*/
+/*	$NetBSD: ipsec_dump_policy.c,v 1.7.6.1 2007/08/01 11:52:17 vanhu Exp $	*/
 
 /* Id: ipsec_dump_policy.c,v 1.10 2005/06/29 09:12:37 manubsd Exp */
 
@@ -53,10 +53,7 @@
 #include "libpfkey.h"
 
 static const char *ipsp_dir_strs[] = {
-	"any", "in", "out", "fwd",
-#ifdef __linux__
-	"in(socket)", "out(socket)"
-#endif
+	"any", "in", "out", "fwd"
 };
 
 static const char *ipsp_policy_strs[] = {
@@ -168,8 +165,6 @@
 	case IPSEC_DIR_OUTBOUND:
 #ifdef HAVE_POLICY_FWD
 	case IPSEC_DIR_FWD:
-	case IPSEC_DIR_FWD + 1:
-	case IPSEC_DIR_FWD + 2:
 #endif
 		break;
 	default:
diff --git a/src/libipsec/ipsec_get_policylen.c b/src/libipsec/ipsec_get_policylen.c
index 5a49778..2f4f6e9 100644
--- a/src/libipsec/ipsec_get_policylen.c
+++ b/src/libipsec/ipsec_get_policylen.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_get_policylen.c,v 1.7 2007/07/18 12:07:50 vanhu Exp $	*/
+/*	$NetBSD: ipsec_get_policylen.c,v 1.6.6.1 2007/08/01 11:52:17 vanhu Exp $	*/
 
 /*	$KAME: ipsec_get_policylen.c,v 1.5 2000/05/07 05:25:03 itojun Exp $	*/
 
diff --git a/src/libipsec/ipsec_set_policy.3 b/src/libipsec/ipsec_set_policy.3
index f3832b5..643b582 100644
--- a/src/libipsec/ipsec_set_policy.3
+++ b/src/libipsec/ipsec_set_policy.3
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ipsec_set_policy.3,v 1.15 2010/03/05 06:47:58 tteras Exp $
+.\"	$NetBSD: ipsec_set_policy.3,v 1.13 2006/09/09 16:22:09 manu Exp $
 .\"
 .\"	$KAME: ipsec_set_policy.3,v 1.16 2003/01/06 21:59:03 sumikawa Exp $
 .\"
@@ -124,10 +124,14 @@
 support policy priorities (Linux \*[Gt]= 2.6.6).
 It takes one of the following formats:
 .Bl -tag  -width "discard"
-.It Ar {priority,prio} offset
+.It Xo
+.Ar {priority,prio} offset
+.Xc
 .Ar offset
-is an integer in the range \-2147483647..214783648.
-.It Ar {priority,prio} base {+,-} offset
+is an integer in the range -2147483647..214783648.
+.It Xo
+.Ar {priority,prio} base {+,-} offset
+.Xc
 .Ar base
 is either
 .Li low (-1073741824) ,
@@ -158,7 +162,12 @@
 means to bypass the IPsec processing.
 .Pq the packet will be transmitted in clear .
 This is for privileged sockets.
-.It Ar direction Bo Ar priority specification Bc Li ipsec Ar request ...
+.It Xo
+.Ar direction
+.Bq Ar priority specification
+.Li ipsec
+.Ar request ...
+.Xc
 .Li ipsec
 means that the matching packets are subject to IPsec processing.
 .Li ipsec
@@ -166,7 +175,16 @@
 .Ar request
 strings, which are formatted as below:
 .Bl -tag  -width "discard"
-.It Ar protocol Li / Ar mode Li / Ar src Li - Ar dst Op Ar /level
+.It Xo
+.Ar protocol
+.Li /
+.Ar mode
+.Li /
+.Ar src
+.Li -
+.Ar dst
+.Op Ar /level
+.Xc
 .Ar protocol
 is either
 .Li ah ,
diff --git a/src/libipsec/ipsec_strerror.c b/src/libipsec/ipsec_strerror.c
index ca26d0e..ad1ab2a 100644
--- a/src/libipsec/ipsec_strerror.c
+++ b/src/libipsec/ipsec_strerror.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_strerror.c,v 1.6 2010/04/07 14:53:52 vanhu Exp $	*/
+/*	$NetBSD: ipsec_strerror.c,v 1.4.6.1 2007/08/01 11:52:17 vanhu Exp $	*/
 
 /*	$KAME: ipsec_strerror.c,v 1.7 2000/07/30 00:45:12 itojun Exp $	*/
 
@@ -63,7 +63,7 @@
 "Invalid key length",				/*EIPSEC_INVAL_KEYLEN*/
 "Invalid address family",			/*EIPSEC_INVAL_FAMILY*/
 "Invalid prefix length",			/*EIPSEC_INVAL_PREFIXLEN*/
-"Invalid direction",				/*EIPSEC_INVAL_DIR*/
+"Invalid direciton",				/*EIPSEC_INVAL_DIR*/
 "SPI range violation",				/*EIPSEC_INVAL_SPI*/
 "No protocol specified",			/*EIPSEC_NO_PROTO*/
 "No algorithm specified",			/*EIPSEC_NO_ALGS*/
diff --git a/src/libipsec/key_debug.c b/src/libipsec/key_debug.c
index e381a98..60f1602 100644
--- a/src/libipsec/key_debug.c
+++ b/src/libipsec/key_debug.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: key_debug.c,v 1.9 2008/12/05 06:02:20 tteras Exp $	*/
+/*	$NetBSD: key_debug.c,v 1.7.6.1 2007/08/01 11:52:18 vanhu Exp $	*/
 
 /*	$KAME: key_debug.c,v 1.29 2001/08/16 14:25:41 itojun Exp $	*/
 
@@ -91,10 +91,6 @@
 static void kdebug_sadb_x_packet __P((struct sadb_ext *));
 #endif
 
-#ifdef SADB_X_EXT_KMADDRESS
-static void kdebug_sadb_x_kmaddress __P((struct sadb_ext *));
-#endif
-
 #ifdef _KERNEL
 static void kdebug_secreplay __P((struct secreplay *));
 #endif
@@ -198,11 +194,6 @@
 			kdebug_sadb_x_packet(ext);
 			break;
 #endif
-#ifdef SADB_X_EXT_KMADDRESS
-		case SADB_X_EXT_KMADDRESS:
-			kdebug_sadb_x_kmaddress(ext);
-			break;
-#endif
 		default:
 			printf("kdebug_sadb: invalid ext_type %u was passed.\n",
 			    ext->sadb_ext_type);
@@ -565,48 +556,6 @@
 }
 #endif
 
-#ifdef SADB_X_EXT_KMADDRESS
-static void
-kdebug_sadb_x_kmaddress(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_x_kmaddress *kma = (struct sadb_x_kmaddress *)ext;
-	struct sockaddr * sa;
-	sa_family_t family;
-	int len, sa_len;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_x_kmaddress: NULL pointer was passed.\n");
-
-	len = (PFKEY_UNUNIT64(kma->sadb_x_kmaddress_len) - sizeof(*kma));
-
-	printf("sadb_x_kmaddress{ reserved=0x%02x%02x%02x%02x }\n",
-	       ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[0],
-	       ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[1],
-	       ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[2],
-	       ((u_char *)(void *)&kma->sadb_x_kmaddress_reserved)[3]);
-
-	sa = (struct sockaddr *)(kma + 1);
-	if (len < sizeof(struct sockaddr) || (sa_len = sysdep_sa_len(sa)) > len)
-		panic("kdebug_sadb_x_kmaddress: not enough data to read"
-		      " first sockaddr.\n");
-	kdebug_sockaddr((void *)sa); /* local address */
-	family = sa->sa_family;
-
-	len -= sa_len;
-	sa = (struct sockaddr *)((char *)sa + sa_len);
-	if (len < sizeof(struct sockaddr) || sysdep_sa_len(sa) > len)
-		panic("kdebug_sadb_x_kmaddress: not enough data to read"
-		      " second sockaddr.\n");
-	kdebug_sockaddr((void *)sa); /* remote address */
-
-	if (family != sa->sa_family)
-		printf("kdebug_sadb_x_kmaddress:  !!!! Please, note the "
-		       "unexpected mismatch in address family.\n");
-}
-#endif
-
 
 #ifdef _KERNEL
 /* %%%: about SPD and SAD */
diff --git a/src/libipsec/libpfkey.h b/src/libipsec/libpfkey.h
index ff4c603..e7e369f 100644
--- a/src/libipsec/libpfkey.h
+++ b/src/libipsec/libpfkey.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: libpfkey.h,v 1.18 2010/12/03 14:32:52 tteras Exp $	*/
+/*	$NetBSD: libpfkey.h,v 1.12.4.1 2007/08/01 11:52:18 vanhu Exp $	*/
 
 /* Id: libpfkey.h,v 1.13 2005/12/04 20:26:43 manubsd Exp */
 
@@ -37,10 +37,6 @@
 #ifndef KAME_LIBPFKEY_H
 #define KAME_LIBPFKEY_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #define PRIORITY_LOW        0xC0000000
 #define PRIORITY_DEFAULT    0x80000000
 #define PRIORITY_HIGH       0x40000000
@@ -121,10 +117,6 @@
 u_int pfkey_get_softrate __P((u_int));
 int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *,
 	struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t));
-int pfkey_send_getspi_nat __P((int, u_int, u_int,
-	struct sockaddr *, struct sockaddr *, u_int8_t, u_int16_t, u_int16_t,
-	u_int32_t, u_int32_t, u_int32_t, u_int32_t));
-
 int pfkey_send_update2 __P((struct pfkey_send_sa_args *));
 int pfkey_send_add2 __P((struct pfkey_send_sa_args *)); 
 int pfkey_send_delete __P((int, u_int, u_int,
@@ -158,22 +150,12 @@
 int pfkey_send_spdflush __P((int));
 int pfkey_send_spddump __P((int));
 #ifdef SADB_X_MIGRATE
-int pfkey_send_migrate __P((int, struct sockaddr *, struct sockaddr *,
-        struct sockaddr *, u_int, struct sockaddr *, u_int, u_int,
-        caddr_t, int, u_int32_t));
+int pfkey_send_migrate __P((int, struct sockaddr *, u_int,
+	struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
 #endif
 
-/* XXX should be somewhere else !!!
- */
-#ifdef SADB_X_EXT_NAT_T_TYPE
-#define PFKEY_ADDR_X_PORT(ext) (ntohs(((struct sadb_x_nat_t_port *)ext)->sadb_x_nat_t_port_port))
-#define PFKEY_ADDR_X_NATTYPE(ext) ( ext != NULL && ((struct sadb_x_nat_t_type *)ext)->sadb_x_nat_t_type_type )
-#endif
-
-
 int pfkey_open __P((void));
 void pfkey_close __P((int));
-int pfkey_set_buffer_size __P((int, int));
 struct sadb_msg *pfkey_recv __P((int));
 int pfkey_send __P((int, struct sadb_msg *, int));
 int pfkey_align __P((struct sadb_msg *, caddr_t *));
@@ -214,10 +196,6 @@
 #define IPPROTO_IPCOMP IPPROTO_COMP
 #endif
 
-#ifndef IPPROTO_MH
-#define IPPROTO_MH		135
-#endif
-
 static __inline u_int8_t
 sysdep_sa_len (const struct sockaddr *sa)
 {
@@ -237,10 +215,6 @@
 }
 #endif
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* KAME_LIBPFKEY_H */
 
 #endif /* _LIBPFKEY_H */
diff --git a/src/libipsec/pfkey.c b/src/libipsec/pfkey.c
index e64cf36..fae0415 100644
--- a/src/libipsec/pfkey.c
+++ b/src/libipsec/pfkey.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey.c,v 1.21 2011/01/20 16:08:35 vanhu Exp $	*/
+/*	$NetBSD: pfkey.c,v 1.13.4.2 2007/10/15 16:05:22 vanhu Exp $	*/
 
 /*	$KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $	*/
 
@@ -71,12 +71,6 @@
 	u_int, u_int, u_int32_t));
 static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
 	struct sockaddr *, u_int, u_int));
-
-#ifdef SADB_X_EXT_KMADDRESS
-static caddr_t pfkey_setsadbkmaddr __P((caddr_t, caddr_t, struct sockaddr *,
-	struct sockaddr *));
-#endif
-
 static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
 static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
 	u_int32_t, u_int32_t, u_int32_t));
@@ -380,10 +374,11 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_getspi_nat(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int8_t natt_type, u_int16_t sport,
-    u_int16_t dport, u_int32_t min, u_int32_t max, u_int32_t reqid,
-    u_int32_t seq)
+pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
+	int so;
+	u_int satype, mode;
+	struct sockaddr *src, *dst;
+	u_int32_t min, max, reqid, seq;
 {
 	struct sadb_msg *newmsg;
 	caddr_t ep;
@@ -430,14 +425,6 @@
 		len += sizeof(struct sadb_spirange);
 	}
 
-#ifdef SADB_X_EXT_NAT_T_TYPE
-	if(natt_type||sport||dport){
-		len += sizeof(struct sadb_x_nat_t_type);
-		len += sizeof(struct sadb_x_nat_t_port);
-		len += sizeof(struct sadb_x_nat_t_port);
-	}
-#endif
-
 	if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
 		__ipsec_set_strerror(strerror(errno));
 		return -1;
@@ -473,32 +460,6 @@
 		return -1;
 	}
 
-#ifdef SADB_X_EXT_NAT_T_TYPE
-	/* Add nat-t messages */
-	if (natt_type) {
-		p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, 
-					natt_type);
-		if (!p) {
-			free(newmsg);
-			return -1;
-		}
-
-		p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT,
-					sport);
-		if (!p) {
-			free(newmsg);
-			return -1;
-		}
-
-		p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT,
-					dport);
-		if (!p) {
-			free(newmsg);
-			return -1;
-		}
-	}
-#endif
-
 	/* proccessing spi range */
 	if (need_spirange) {
 		struct sadb_spirange spirange;
@@ -534,15 +495,6 @@
 	return len;
 }
 
-int
-pfkey_send_getspi(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t min, u_int32_t max, u_int32_t reqid,
-    u_int32_t seq)
-{
-	return pfkey_send_getspi_nat(so, satype, mode, src, dst, 0, 0, 0,
-		min, max, reqid, seq);
-}
-
 /*
  * sending SADB_UPDATE message to the kernel.
  * The length of key material is a_keylen + e_keylen.
@@ -551,10 +503,12 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_update2(struct pfkey_send_sa_args *sa_parms)
+pfkey_send_update2(sa_parms)
+	struct pfkey_send_sa_args *sa_parms;
 {
 	int len;
 
+	
 	sa_parms->type = SADB_UPDATE;
 	if ((len = pfkey_send_x1(sa_parms)) < 0)
 		return -1;
@@ -570,7 +524,8 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_add2(struct pfkey_send_sa_args *sa_parms)
+pfkey_send_add2(sa_parms)
+	struct pfkey_send_sa_args *sa_parms;
 {
 	int len;
 	
@@ -588,8 +543,11 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_delete(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t spi)
+pfkey_send_delete(so, satype, mode, src, dst, spi)
+	int so;
+	u_int satype, mode;
+	struct sockaddr *src, *dst;
+	u_int32_t spi;
 {
 	int len;
 	if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
@@ -609,8 +567,10 @@
  */
 /*ARGSUSED*/
 int
-pfkey_send_delete_all(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst)
+pfkey_send_delete_all(so, satype, mode, src, dst)
+	int so;
+	u_int satype, mode;
+	struct sockaddr *src, *dst;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -689,8 +649,11 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_get(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t spi)
+pfkey_send_get(so, satype, mode, src, dst, spi)
+	int so;
+	u_int satype, mode;
+	struct sockaddr *src, *dst;
+	u_int32_t spi;
 {
 	int len;
 	if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
@@ -706,7 +669,9 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_register(int so, u_int satype)
+pfkey_send_register(so, satype)
+	int so;
+	u_int satype;
 {
 	int len, algno;
 
@@ -746,7 +711,8 @@
  *	-1: error occured, and set errno.
  */
 int
-pfkey_recv_register(int so)
+pfkey_recv_register(so)
+	int so;
 {
 	pid_t pid = getpid();
 	struct sadb_msg *newmsg;
@@ -785,7 +751,9 @@
  *	-1: error occured, and set errno.
  */
 int
-pfkey_set_supported(struct sadb_msg *msg, int tlen)
+pfkey_set_supported(msg, tlen)
+	struct sadb_msg *msg;
+	int tlen;
 {
 	struct sadb_supported *sup;
 	caddr_t p;
@@ -847,7 +815,9 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_flush(int so, u_int satype)
+pfkey_send_flush(so, satype)
+	int so;
+	u_int satype;
 {
 	int len;
 
@@ -864,7 +834,9 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_dump(int so, u_int satype)
+pfkey_send_dump(so, satype)
+	int so;
+	u_int satype;
 {
 	int len;
 
@@ -887,7 +859,9 @@
  *	        algorithms is.
  */
 int
-pfkey_send_promisc_toggle(int so, int flag)
+pfkey_send_promisc_toggle(so, flag)
+	int so;
+	int flag;
 {
 	int len;
 
@@ -905,9 +879,13 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdadd(int so, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
-    int policylen, u_int32_t seq)
+pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	int len;
 
@@ -927,9 +905,15 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdadd2(int so, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime,
-    u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq)
+pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
+		policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	u_int64_t ltime, vtime;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	int len;
 
@@ -949,9 +933,13 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdupdate(int so, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
-    int policylen, u_int32_t seq)
+pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	int len;
 
@@ -971,9 +959,15 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdupdate2(int so, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime,
-    u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq)
+pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
+		policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	u_int64_t ltime, vtime;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	int len;
 
@@ -993,9 +987,13 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spddelete(int so, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
-    int policylen, u_int32_t seq)
+pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	int len;
 
@@ -1020,7 +1018,9 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spddelete2(int so, u_int32_t spid)
+pfkey_send_spddelete2(so, spid)
+	int so;
+	u_int32_t spid;
 {
 	int len;
 
@@ -1037,7 +1037,9 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdget(int so, u_int32_t spid)
+pfkey_send_spdget(so, spid)
+	int so;
+	u_int32_t spid;
 {
 	int len;
 
@@ -1054,9 +1056,13 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdsetidx(int so, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
-    int policylen, u_int32_t seq)
+pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	int len;
 
@@ -1081,7 +1087,8 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spdflush(int so)
+pfkey_send_spdflush(so)
+	int so;
 {
 	int len;
 
@@ -1098,7 +1105,8 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_spddump(int so)
+pfkey_send_spddump(so)
+	int so;
 {
 	int len;
 
@@ -1117,9 +1125,13 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_migrate(int so, struct sockaddr *local, struct sockaddr *remote,
-    struct sockaddr *src, u_int prefs, struct sockaddr *dst, u_int prefd,
-    u_int proto, caddr_t policy, int policylen, u_int32_t seq)
+pfkey_send_migrate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int prefs, prefd, proto;
+	caddr_t policy;
+	int policylen;
+	u_int32_t seq;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -1137,17 +1149,6 @@
 		return -1;
 	}
 
-	if (local == NULL || remote == NULL) {
-		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
-		return -1;
-	}
-#ifdef SADB_X_EXT_KMADDRESS
-	if (local->sa_family != remote->sa_family) {
-		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
-		return -1;
-	}
-#endif
-
 	switch (src->sa_family) {
 	case AF_INET:
 		plen = sizeof(struct in_addr) << 3;
@@ -1166,10 +1167,6 @@
 
 	/* create new sadb_msg to reply. */
 	len = sizeof(struct sadb_msg)
-#ifdef SADB_X_EXT_KMADDRESS
-		+ sizeof(struct sadb_x_kmaddress)
-		+ PFKEY_ALIGN8(2*sysdep_sa_len(local))
-#endif
 		+ sizeof(struct sadb_address)
 		+ PFKEY_ALIGN8(sysdep_sa_len(src))
 		+ sizeof(struct sadb_address)
@@ -1188,13 +1185,6 @@
 		free(newmsg);
 		return -1;
 	}
-#ifdef SADB_X_EXT_KMADDRESS
-	p = pfkey_setsadbkmaddr(p, ep, local, remote);
-	if (!p) {
-		free(newmsg);
-		return -1;
-	}
-#endif
 	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
 	if (!p) {
 		free(newmsg);
@@ -1222,7 +1212,8 @@
 
 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
 static int
-pfkey_send_x1(struct pfkey_send_sa_args *sa_parms)
+pfkey_send_x1(sa_parms)
+	struct pfkey_send_sa_args *sa_parms;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -1495,8 +1486,11 @@
 /* sending SADB_DELETE or SADB_GET message to the kernel */
 /*ARGSUSED*/
 static int
-pfkey_send_x2(int so, u_int type, u_int satype, u_int mode,
-    struct sockaddr *src, struct sockaddr *dst, u_int32_t spi)
+pfkey_send_x2(so, type, satype, mode, src, dst, spi)
+	int so;
+	u_int type, satype, mode;
+	struct sockaddr *src, *dst;
+	u_int32_t spi;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -1579,7 +1573,9 @@
  * to the kernel
  */
 static int
-pfkey_send_x3(int so, u_int type, u_int satype)
+pfkey_send_x3(so, type, satype)
+	int so;
+	u_int type, satype;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -1639,9 +1635,15 @@
 
 /* sending SADB_X_SPDADD message to the kernel */
 static int
-pfkey_send_x4(int so, u_int type, struct sockaddr *src, u_int prefs,
-    struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime,
-    u_int64_t vtime, char *policy, int policylen, u_int32_t seq)
+pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
+		ltime, vtime, policy, policylen, seq)
+	int so;
+	struct sockaddr *src, *dst;
+	u_int type, prefs, prefd, proto;
+	u_int64_t ltime, vtime;
+	char *policy;
+	int policylen;
+	u_int32_t seq;
 {
 	struct sadb_msg *newmsg;
 	int len;
@@ -1727,7 +1729,10 @@
 
 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
 static int
-pfkey_send_x5(int so, u_int type, u_int32_t spid)
+pfkey_send_x5(so, type, spid)
+	int so;
+	u_int type;
+	u_int32_t spid;
 {
 	struct sadb_msg *newmsg;
 	struct sadb_x_policy xpl;
@@ -1780,7 +1785,7 @@
  *	others : success and return value of socket.
  */
 int
-pfkey_open(void)
+pfkey_open()
 {
 	int so;
 	int bufsiz = 128 * 1024;	/*is 128K enough?*/
@@ -1806,42 +1811,6 @@
 	return so;
 }
 
-int
-pfkey_set_buffer_size(int so, int size)
-{
-	int newsize;
-	int actual_bufsiz;
-	socklen_t sizebufsiz;
-	int desired_bufsiz;
-
-	/*
-	 * on linux you may need to allow the kernel to allocate
-	 * more buffer space by increasing:
-	 * /proc/sys/net/core/rmem_max and wmem_max
-	 */
-	if (size > 0) {
-		actual_bufsiz = 0;
-		sizebufsiz = sizeof(actual_bufsiz);
-		desired_bufsiz = size * 1024;
-		if ((getsockopt(so, SOL_SOCKET, SO_RCVBUF,
-				&actual_bufsiz, &sizebufsiz) < 0)
-		    || (actual_bufsiz < desired_bufsiz)) {
-			if (setsockopt(so, SOL_SOCKET, SO_RCVBUF,
-				       &desired_bufsiz, sizeof(desired_bufsiz)) < 0) {
-				__ipsec_set_strerror(strerror(errno));
-				return -1;
-			}
-		}
-	}
-
-	/* return actual buffer size */
-	actual_bufsiz = 0;
-	sizebufsiz = sizeof(actual_bufsiz);
-	getsockopt(so, SOL_SOCKET, SO_RCVBUF,
-		   &actual_bufsiz, &sizebufsiz);
-	return actual_bufsiz / 1024;
-}
-
 /*
  * close a socket.
  * OUT:
@@ -1849,7 +1818,8 @@
  *	-1: fail.
  */
 void
-pfkey_close(int so)
+pfkey_close(so)
+	int so;
 {
 	(void)close(so);
 
@@ -1867,7 +1837,8 @@
  * XXX should be rewritten to pass length explicitly
  */
 struct sadb_msg *
-pfkey_recv(int so)
+pfkey_recv(so)
+	int so;
 {
 	struct sadb_msg buf, *newmsg;
 	int len, reallen;
@@ -1924,7 +1895,10 @@
  *	-1     : fail.
  */
 int
-pfkey_send(int so, struct sadb_msg *msg, int len)
+pfkey_send(so, msg, len)
+	int so;
+	struct sadb_msg *msg;
+	int len;
 {
 	if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) {
 		__ipsec_set_strerror(strerror(errno));
@@ -1950,7 +1924,9 @@
  * XXX should be rewritten to obtain length explicitly
  */
 int
-pfkey_align(struct sadb_msg *msg, caddr_t *mhp)
+pfkey_align(msg, mhp)
+	struct sadb_msg *msg;
+	caddr_t *mhp;
 {
 	struct sadb_ext *ext;
 	int i;
@@ -2025,9 +2001,6 @@
 #ifdef SADB_X_EXT_PACKET
 		case SADB_X_EXT_PACKET:
 #endif
-#ifdef SADB_X_EXT_KMADDRESS
-		case SADB_X_EXT_KMADDRESS:
-#endif
 #ifdef SADB_X_EXT_SEC_CTX
 		case SADB_X_EXT_SEC_CTX:
 #endif
@@ -2062,7 +2035,8 @@
  *	 0: valid.
  */
 int
-pfkey_check(caddr_t *mhp)
+pfkey_check(mhp)
+	caddr_t *mhp;
 {
 	struct sadb_msg *msg;
 
@@ -2138,12 +2112,6 @@
 			break;
 		/*FALLTHROUGH*/
 	default:
-#ifdef __linux__
-		/* Linux kernel seems to be buggy and return
-		 * uninitialized satype for spd flush message */
-		if (msg->sadb_msg_type == SADB_X_SPDFLUSH)
-			break;
-#endif
 		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
 		return -1;
 	}
@@ -2191,8 +2159,13 @@
  * `buf' must has been allocated sufficiently.
  */
 static caddr_t
-pfkey_setsadbmsg(caddr_t buf, caddr_t lim, u_int type, u_int tlen,
-    u_int satype, u_int32_t seq, pid_t pid)
+pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type, satype;
+	u_int tlen;
+	u_int32_t seq;
+	pid_t pid;
 {
 	struct sadb_msg *p;
 	u_int len;
@@ -2221,8 +2194,11 @@
  * `buf' must has been allocated sufficiently.
  */
 static caddr_t
-pfkey_setsadbsa(caddr_t buf, caddr_t lim, u_int32_t spi, u_int wsize,
-    u_int auth, u_int enc, u_int32_t flags)
+pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
+	caddr_t buf;
+	caddr_t lim;
+	u_int32_t spi, flags;
+	u_int wsize, auth, enc;
 {
 	struct sadb_sa *p;
 	u_int len;
@@ -2252,8 +2228,13 @@
  * prefixlen is in bits.
  */
 static caddr_t
-pfkey_setsadbaddr(caddr_t buf, caddr_t lim, u_int exttype,
-    struct sockaddr *saddr, u_int prefixlen, u_int ul_proto)
+pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
+	caddr_t buf;
+	caddr_t lim;
+	u_int exttype;
+	struct sockaddr *saddr;
+	u_int prefixlen;
+	u_int ul_proto;
 {
 	struct sadb_address *p;
 	u_int len;
@@ -2276,50 +2257,16 @@
 	return(buf + len);
 }
 
-#ifdef SADB_X_EXT_KMADDRESS
-/*
- * set data into sadb_x_kmaddress.
- * `buf' must has been allocated sufficiently.
- */
-static caddr_t
-pfkey_setsadbkmaddr(caddr_t buf, caddr_t lim, struct sockaddr *local,
-    struct sockaddr *remote)
-{
-	struct sadb_x_kmaddress *p;
-	struct sockaddr *sa;
-	u_int salen = sysdep_sa_len(local);
-	u_int len;
-
-	/* sanity check */
-	if (local->sa_family != remote->sa_family)
-		return NULL;
-
-	p = (void *)buf;
-	len = sizeof(struct sadb_x_kmaddress) + PFKEY_ALIGN8(2*salen);
-
-	if (buf + len > lim)
-		return NULL;
-
-	memset(p, 0, len);
-	p->sadb_x_kmaddress_len = PFKEY_UNIT64(len);
-	p->sadb_x_kmaddress_exttype = SADB_X_EXT_KMADDRESS;
-	p->sadb_x_kmaddress_reserved = 0;
-	sa = (struct sockaddr *)(p + 1);
-	memcpy(sa, local, salen);
-	sa = (struct sockaddr *)((char *)sa + salen);
-	memcpy(sa, remote, salen);
-
-	return(buf + len);
-}
-#endif
-
 /*
  * set sadb_key structure after clearing buffer with zero.
  * OUT: the pointer of buf + len.
  */
 static caddr_t
-pfkey_setsadbkey(caddr_t buf, caddr_t lim, u_int type, caddr_t key,
-    u_int keylen)
+pfkey_setsadbkey(buf, lim, type, key, keylen)
+	caddr_t buf;
+	caddr_t lim;
+	caddr_t key;
+	u_int type, keylen;
 {
 	struct sadb_key *p;
 	u_int len;
@@ -2346,8 +2293,11 @@
  * OUT: the pointer of buf + len.
  */
 static caddr_t
-pfkey_setsadblifetime(caddr_t buf, caddr_t lim, u_int type, u_int32_t l_alloc,
-    u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime)
+pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type;
+	u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
 {
 	struct sadb_lifetime *p;
 	u_int len;
@@ -2389,7 +2339,11 @@
  * `buf' must has been allocated sufficiently.
  */
 static caddr_t
-pfkey_setsadbxsa2(caddr_t buf, caddr_t lim, u_int32_t mode0, u_int32_t reqid)
+pfkey_setsadbxsa2(buf, lim, mode0, reqid)
+	caddr_t buf;
+	caddr_t lim;
+	u_int32_t mode0;
+	u_int32_t reqid;
 {
 	struct sadb_x_sa2 *p;
 	u_int8_t mode = mode0 & 0xff;
@@ -2412,7 +2366,11 @@
 
 #ifdef SADB_X_EXT_NAT_T_TYPE
 static caddr_t
-pfkey_set_natt_type(caddr_t buf, caddr_t lim, u_int type, u_int8_t l_natt_type)
+pfkey_set_natt_type(buf, lim, type, l_natt_type)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type;
+	u_int8_t l_natt_type;
 {
 	struct sadb_x_nat_t_type *p;
 	u_int len;
@@ -2432,7 +2390,11 @@
 }
 
 static caddr_t
-pfkey_set_natt_port(caddr_t buf, caddr_t lim, u_int type, u_int16_t l_natt_port)
+pfkey_set_natt_port(buf, lim, type, l_natt_port)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type;
+	u_int16_t l_natt_port;
 {
 	struct sadb_x_nat_t_port *p;
 	u_int len;
@@ -2454,8 +2416,11 @@
 
 #ifdef SADB_X_EXT_NAT_T_FRAG
 static caddr_t
-pfkey_set_natt_frag(caddr_t buf, caddr_t lim, u_int type, 
-    u_int16_t l_natt_frag)
+pfkey_set_natt_frag(buf, lim, type, l_natt_frag)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type;
+	u_int16_t l_natt_frag;
 {
 	struct sadb_x_nat_t_frag *p;
 	u_int len;
@@ -2477,8 +2442,13 @@
 
 #ifdef SADB_X_EXT_SEC_CTX
 static caddr_t
-pfkey_setsecctx(caddr_t buf, caddr_t lim, u_int type, u_int8_t ctx_doi,
-    u_int8_t ctx_alg, caddr_t sec_ctx, u_int16_t sec_ctxlen)
+pfkey_setsecctx(buf, lim, type, ctx_doi, ctx_alg, sec_ctx, sec_ctxlen)
+	caddr_t buf;
+	caddr_t lim;
+	u_int type;
+	u_int8_t ctx_doi, ctx_alg;
+	caddr_t sec_ctx;
+	u_int16_t sec_ctxlen;
 {
 	struct sadb_x_sec_ctx *p;
 	u_int len;
@@ -2507,11 +2477,18 @@
  * libipsec users. Please use pfkey_send_update2 and pfkey_send_add2 instead 
  */
 int
-pfkey_send_update(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize,
-    caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type,
-    u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes,
-    u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq)
+pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
+		keymat, e_type, e_keylen, a_type, a_keylen, flags,
+		l_alloc, l_bytes, l_addtime, l_usetime, seq)
+	int so;
+	u_int satype, mode, wsize;
+	struct sockaddr *src, *dst;
+	u_int32_t spi, reqid;
+	caddr_t keymat;
+	u_int e_type, e_keylen, a_type, a_keylen, flags;
+	u_int32_t l_alloc;
+	u_int64_t l_bytes, l_addtime, l_usetime;
+	u_int32_t seq;
 {
 	struct pfkey_send_sa_args psaa;
 
@@ -2541,13 +2518,24 @@
 }
 
 int
-pfkey_send_update_nat(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize,
-    caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type,
-    u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes,
-    u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq,
-    u_int8_t l_natt_type, u_int16_t l_natt_sport, u_int16_t l_natt_dport,
-    struct sockaddr *l_natt_oa, u_int16_t l_natt_frag)
+pfkey_send_update_nat(so, satype, mode, src, dst, spi, reqid, wsize,
+		      keymat, e_type, e_keylen, a_type, a_keylen, flags,
+		      l_alloc, l_bytes, l_addtime, l_usetime, seq,
+		      l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
+		      l_natt_frag)
+	int so;
+	u_int satype, mode, wsize;
+	struct sockaddr *src, *dst;
+	u_int32_t spi, reqid;
+	caddr_t keymat;
+	u_int e_type, e_keylen, a_type, a_keylen, flags;
+	u_int32_t l_alloc;
+	u_int64_t l_bytes, l_addtime, l_usetime;
+	u_int32_t seq;
+	u_int8_t l_natt_type;
+	u_int16_t l_natt_sport, l_natt_dport;
+	struct sockaddr *l_natt_oa;
+	u_int16_t l_natt_frag;
 {
 	struct pfkey_send_sa_args psaa;
 
@@ -2582,11 +2570,18 @@
 }
 
 int
-pfkey_send_add(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize,
-    caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type,
-    u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes,
-    u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq)
+pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
+		keymat, e_type, e_keylen, a_type, a_keylen, flags,
+		l_alloc, l_bytes, l_addtime, l_usetime, seq)
+	int so;
+	u_int satype, mode, wsize;
+	struct sockaddr *src, *dst;
+	u_int32_t spi, reqid;
+	caddr_t keymat;
+	u_int e_type, e_keylen, a_type, a_keylen, flags;
+	u_int32_t l_alloc;
+	u_int64_t l_bytes, l_addtime, l_usetime;
+	u_int32_t seq;
 {
 	struct pfkey_send_sa_args psaa;
 
@@ -2616,13 +2611,24 @@
 }
 
 int
-pfkey_send_add_nat(int so, u_int satype, u_int mode, struct sockaddr *src,
-    struct sockaddr *dst, u_int32_t spi, u_int32_t reqid, u_int wsize,
-    caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type,
-    u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes,
-    u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq,
-    u_int8_t l_natt_type, u_int16_t l_natt_sport, u_int16_t l_natt_dport,
-    struct sockaddr *l_natt_oa, u_int16_t l_natt_frag)
+pfkey_send_add_nat(so, satype, mode, src, dst, spi, reqid, wsize,
+		      keymat, e_type, e_keylen, a_type, a_keylen, flags,
+		      l_alloc, l_bytes, l_addtime, l_usetime, seq,
+		      l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
+		      l_natt_frag)
+	int so;
+	u_int satype, mode, wsize;
+	struct sockaddr *src, *dst;
+	u_int32_t spi, reqid;
+	caddr_t keymat;
+	u_int e_type, e_keylen, a_type, a_keylen, flags;
+	u_int32_t l_alloc;
+	u_int64_t l_bytes, l_addtime, l_usetime;
+	u_int32_t seq;
+	u_int8_t l_natt_type;
+	u_int16_t l_natt_sport, l_natt_dport;
+	struct sockaddr *l_natt_oa;
+	u_int16_t l_natt_frag;
 {
 	struct pfkey_send_sa_args psaa;
 
diff --git a/src/libipsec/pfkey_dump.c b/src/libipsec/pfkey_dump.c
index 4627ebc..8fa4084 100644
--- a/src/libipsec/pfkey_dump.c
+++ b/src/libipsec/pfkey_dump.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey_dump.c,v 1.18 2010/12/03 14:32:52 tteras Exp $	*/
+/*	$NetBSD: pfkey_dump.c,v 1.15.6.1 2007/08/01 11:52:18 vanhu Exp $	*/
 
 /*	$KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $	*/
 
@@ -716,19 +716,13 @@
 	else
 		snprintf(prefbuf, sizeof(prefbuf), "/%u", pref);
 
-	switch (ulp) {
-	case IPPROTO_ICMP:
-	case IPPROTO_ICMPV6:
-	case IPPROTO_MH:
-	case IPPROTO_GRE:
+	if (ulp == IPPROTO_ICMPV6)
 		memset(portbuf, 0, sizeof(portbuf));
-		break;
-	default:
+	else {
 		if (port == IPSEC_PORT_ANY)
-			strcpy(portbuf, "[any]");
+			snprintf(portbuf, sizeof(portbuf), "[%s]", "any");
 		else
 			snprintf(portbuf, sizeof(portbuf), "[%u]", port);
-		break;
 	}
 
 	snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
@@ -740,26 +734,29 @@
 str_upperspec(ulp, p1, p2)
 	u_int ulp, p1, p2;
 {
-	struct protoent *ent;
+	if (ulp == IPSEC_ULPROTO_ANY)
+		printf("any");
+	else if (ulp == IPPROTO_ICMPV6) {
+		printf("icmp6");
+		if (!(p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY))
+			printf(" %u,%u", p1, p2);
+	} else {
+		struct protoent *ent;
 
-	ent = getprotobynumber((int)ulp);
-	if (ent)
-		printf("%s", ent->p_name);
-	else
-		printf("%u", ulp);
+		switch (ulp) {
+		case IPPROTO_IPV4:
+			printf("ip4");
+			break;
+		default:
+			ent = getprotobynumber((int)ulp);
+			if (ent)
+				printf("%s", ent->p_name);
+			else
+				printf("%u", ulp);
 
-	if (p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY)
-		return;
-
-	switch (ulp) {
-	case IPPROTO_ICMP:
-	case IPPROTO_ICMPV6:
-	case IPPROTO_MH:
-		printf(" %u,%u", p1, p2);
-		break;
-	case IPPROTO_GRE:
-		printf(" %u", (p1 << 16) + p2);
-		break;
+			endprotoent();
+			break;
+		}
 	}
 }
 
@@ -777,10 +774,8 @@
 		for (;i < 20;) buf[i++] = ' ';
 	} else {
 		char *t0;
-		if ((t0 = ctime(&t)) == NULL)
-			memset(buf, '?', 20);
-		else
-			memcpy(buf, t0 + 4, 20);
+		t0 = ctime(&t);
+		memcpy(buf, t0 + 4, 20);
 	}
 
 	buf[20] = '\0';
diff --git a/src/libipsec/policy_parse.h b/src/libipsec/policy_parse.h
index dc629dd..a4c1d0b 100644
--- a/src/libipsec/policy_parse.h
+++ b/src/libipsec/policy_parse.h
@@ -1,23 +1,24 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
 /* Skeleton interface for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -28,11 +29,10 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -80,28 +80,22 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-
-/* Line 1676 of yacc.c  */
 #line 129 "policy_parse.y"
-
+{
 	u_int num;
 	u_int32_t num32;
 	struct _val {
 		int len;
 		char *buf;
 	} val;
-
-
-
-/* Line 1676 of yacc.c  */
-#line 99 "policy_parse.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1489 of yacc.c.  */
+#line 94 "policy_parse.h"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE __libipseclval;
 
-
diff --git a/src/libipsec/policy_parse.y b/src/libipsec/policy_parse.y
index 321f4f0..a13dc12 100644
--- a/src/libipsec/policy_parse.y
+++ b/src/libipsec/policy_parse.y
@@ -1,4 +1,4 @@
-/*	$NetBSD: policy_parse.y,v 1.11 2009/02/16 18:36:21 tteras Exp $	*/
+/*	$NetBSD: policy_parse.y,v 1.9.6.2 2009/02/16 18:38:26 tteras Exp $	*/
 
 /*	$KAME: policy_parse.y,v 1.21 2003/12/12 08:01:26 itojun Exp $	*/
 
diff --git a/src/libipsec/policy_token.l b/src/libipsec/policy_token.l
index 243b678..0833c20 100644
--- a/src/libipsec/policy_token.l
+++ b/src/libipsec/policy_token.l
@@ -1,4 +1,4 @@
-/*	$NetBSD: policy_token.l,v 1.7 2007/07/18 12:07:50 vanhu Exp $	*/
+/*	$NetBSD: policy_token.l,v 1.6.6.1 2007/08/01 11:52:19 vanhu Exp $	*/
 
 /* Id: policy_token.l,v 1.12 2005/05/05 12:32:18 manubsd Exp */
 
diff --git a/src/racoon/Makefile.am b/src/racoon/Makefile.am
index dbaded9..202a18e 100644
--- a/src/racoon/Makefile.am
+++ b/src/racoon/Makefile.am
@@ -3,7 +3,7 @@
 sbin_PROGRAMS = racoon racoonctl plainrsa-gen
 noinst_PROGRAMS = eaytest
 include_racoon_HEADERS = racoonctl.h var.h vmbuf.h misc.h gcmalloc.h admin.h \
-	schedule.h sockmisc.h isakmp_var.h isakmp.h isakmp_xauth.h \
+	schedule.h sockmisc.h vmbuf.h isakmp_var.h isakmp.h isakmp_xauth.h \
 	isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h
 lib_LTLIBRARIES = libracoon.la
 
@@ -48,7 +48,6 @@
 racoonctl_LDADD = libracoon.la ../libipsec/libipsec.la 
 
 libracoon_la_SOURCES = kmpstat.c vmbuf.c sockmisc.c misc.c
-libracoon_la_CFLAGS = -DNOUSE_PRIVSEP $(AM_CFLAGS)
 
 plainrsa_gen_SOURCES = plainrsa-gen.c plog.c \
 	crypto_openssl.c logger.c 
@@ -89,7 +88,6 @@
    ${man5_MANS} ${man8_MANS} \
    missing/crypto/rijndael/boxes-fst.dat \
    doc/FAQ doc/README.certificate doc/README.gssapi doc/README.plainrsa \
-   doc/README.privsep \
    contrib/sp.pl stats.pl \
    samples/psk.txt.sample  samples/racoon.conf.sample \
    samples/psk.txt.in samples/racoon.conf.in \
diff --git a/src/racoon/Makefile.in b/src/racoon/Makefile.in
index 4b4e635..47e997b 100644
--- a/src/racoon/Makefile.in
+++ b/src/racoon/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -21,9 +20,8 @@
 
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
@@ -54,40 +52,21 @@
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
     *) f=$$p;; \
   esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sbindir)" \
 	"$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \
 	"$(DESTDIR)$(include_racoondir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libracoon_la_LIBADD =
-am_libracoon_la_OBJECTS = libracoon_la-kmpstat.lo \
-	libracoon_la-vmbuf.lo libracoon_la-sockmisc.lo \
-	libracoon_la-misc.lo
+am_libracoon_la_OBJECTS = kmpstat.lo vmbuf.lo sockmisc.lo misc.lo
 libracoon_la_OBJECTS = $(am_libracoon_la_OBJECTS)
-libracoon_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libracoon_la_CFLAGS) \
-	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS)
 am_eaytest_OBJECTS = eaytest.$(OBJEXT) plog.$(OBJEXT) logger.$(OBJEXT)
 eaytest_OBJECTS = $(am_eaytest_OBJECTS)
@@ -117,7 +96,6 @@
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
-am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -146,11 +124,10 @@
 man8dir = $(mandir)/man8
 NROFF = nroff
 MANS = $(man5_MANS) $(man8_MANS)
+include_racoonHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(include_racoon_HEADERS) $(noinst_HEADERS)
 ETAGS = etags
 CTAGS = ctags
-am__tty_colors = \
-red=; grn=; lgn=; blu=; std=
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -166,18 +143,23 @@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
 CRYPTOBJS = @CRYPTOBJS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
+ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 EXTRA_CRYPTO = @EXTRA_CRYPTO@
-FGREP = @FGREP@
+F77 = @F77@
+FFLAGS = @FFLAGS@
 FRAG_OBJS = @FRAG_OBJS@
 GLIBC_BUGS = @GLIBC_BUGS@
 GREP = @GREP@
@@ -191,7 +173,6 @@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 KERNEL_INCLUDE = @KERNEL_INCLUDE@
 KRB5_CONFIG = @KRB5_CONFIG@
-LD = @LD@
 LDFLAGS = @LDFLAGS@
 LEX = @LEX@
 LEXLIB = @LEXLIB@
@@ -199,24 +180,18 @@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
 NATT_OBJS = @NATT_OBJS@
-NM = @NM@
 NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 PACKAGE_NAME = @PACKAGE_NAME@
 PACKAGE_STRING = @PACKAGE_STRING@
 PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
@@ -234,7 +209,8 @@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -266,7 +242,6 @@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -279,11 +254,10 @@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 include_racoon_HEADERS = racoonctl.h var.h vmbuf.h misc.h gcmalloc.h admin.h \
-	schedule.h sockmisc.h isakmp_var.h isakmp.h isakmp_xauth.h \
+	schedule.h sockmisc.h vmbuf.h isakmp_var.h isakmp.h isakmp_xauth.h \
 	isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h
 
 lib_LTLIBRARIES = libracoon.la
@@ -328,7 +302,6 @@
 racoonctl_SOURCES = racoonctl.c str2val.c 
 racoonctl_LDADD = libracoon.la ../libipsec/libipsec.la 
 libracoon_la_SOURCES = kmpstat.c vmbuf.c sockmisc.c misc.c
-libracoon_la_CFLAGS = -DNOUSE_PRIVSEP $(AM_CFLAGS)
 plainrsa_gen_SOURCES = plainrsa-gen.c plog.c \
 	crypto_openssl.c logger.c 
 
@@ -368,7 +341,6 @@
    ${man5_MANS} ${man8_MANS} \
    missing/crypto/rijndael/boxes-fst.dat \
    doc/FAQ doc/README.certificate doc/README.gssapi doc/README.plainrsa \
-   doc/README.privsep \
    contrib/sp.pl stats.pl \
    samples/psk.txt.sample  samples/racoon.conf.sample \
    samples/psk.txt.in samples/racoon.conf.in \
@@ -390,14 +362,14 @@
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/racoon/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign src/racoon/Makefile
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/racoon/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  src/racoon/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -415,28 +387,23 @@
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
 	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
-	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-	list2=; for p in $$list; do \
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
 	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
+	    f=$(am__strip_dir) \
+	    echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+	    $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
 	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-	}
+	done
 
 uninstall-libLTLIBRARIES:
 	@$(NORMAL_UNINSTALL)
-	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  p=$(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
 	done
 
 clean-libLTLIBRARIES:
@@ -448,59 +415,42 @@
 	  rm -f "$${dir}/so_locations"; \
 	done
 libracoon.la: $(libracoon_la_OBJECTS) $(libracoon_la_DEPENDENCIES) 
-	$(libracoon_la_LINK) -rpath $(libdir) $(libracoon_la_OBJECTS) $(libracoon_la_LIBADD) $(LIBS)
+	$(LINK) -rpath $(libdir) $(libracoon_la_OBJECTS) $(libracoon_la_LIBADD) $(LIBS)
 
 clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
+	@list='$(noinst_PROGRAMS)'; for p in $$list; do \
+	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  echo " rm -f $$p $$f"; \
+	  rm -f $$p $$f ; \
+	done
 install-sbinPROGRAMS: $(sbin_PROGRAMS)
 	@$(NORMAL_INSTALL)
 	test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
-	@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
-	for p in $$list; do echo "$$p $$p"; done | \
-	sed 's/$(EXEEXT)$$//' | \
-	while read p p1; do if test -f $$p || test -f $$p1; \
-	  then echo "$$p"; echo "$$p"; else :; fi; \
-	done | \
-	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
-	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
-	sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
-	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
-	    else { print "f", $$3 "/" $$4, $$1; } } \
-	  END { for (d in files) print "f", d, files[d] }' | \
-	while read type dir files; do \
-	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-	    test -z "$$files" || { \
-	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
-	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
-	    } \
-	; done
+	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	     || test -f $$p1 \
+	  ; then \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+	   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+	  else :; fi; \
+	done
 
 uninstall-sbinPROGRAMS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
-	files=`for p in $$list; do echo "$$p"; done | \
-	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-	      -e 's/$$/$(EXEEXT)/' `; \
-	test -n "$$list" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+	done
 
 clean-sbinPROGRAMS:
-	@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
+	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  echo " rm -f $$p $$f"; \
+	  rm -f $$p $$f ; \
+	done
 eaytest$(EXEEXT): $(eaytest_OBJECTS) $(eaytest_DEPENDENCIES) 
 	@rm -f eaytest$(EXEEXT)
 	$(LINK) $(eaytest_OBJECTS) $(eaytest_LDADD) $(LIBS)
@@ -556,13 +506,11 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_quick.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_unity.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isakmp_xauth.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-kmpstat.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-misc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-sockmisc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libracoon_la-vmbuf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kmpstat.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localconf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nattraversal.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oakley.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey.Po@am__quote@
@@ -584,77 +532,51 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockmisc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str2val.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnames.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/throttle.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vendorid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmbuf.Plo@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(COMPILE) -c $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
 
-libracoon_la-kmpstat.lo: kmpstat.c
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-kmpstat.lo -MD -MP -MF $(DEPDIR)/libracoon_la-kmpstat.Tpo -c -o libracoon_la-kmpstat.lo `test -f 'kmpstat.c' || echo '$(srcdir)/'`kmpstat.c
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libracoon_la-kmpstat.Tpo $(DEPDIR)/libracoon_la-kmpstat.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='kmpstat.c' object='libracoon_la-kmpstat.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-kmpstat.lo `test -f 'kmpstat.c' || echo '$(srcdir)/'`kmpstat.c
-
-libracoon_la-vmbuf.lo: vmbuf.c
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-vmbuf.lo -MD -MP -MF $(DEPDIR)/libracoon_la-vmbuf.Tpo -c -o libracoon_la-vmbuf.lo `test -f 'vmbuf.c' || echo '$(srcdir)/'`vmbuf.c
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libracoon_la-vmbuf.Tpo $(DEPDIR)/libracoon_la-vmbuf.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='vmbuf.c' object='libracoon_la-vmbuf.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-vmbuf.lo `test -f 'vmbuf.c' || echo '$(srcdir)/'`vmbuf.c
-
-libracoon_la-sockmisc.lo: sockmisc.c
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-sockmisc.lo -MD -MP -MF $(DEPDIR)/libracoon_la-sockmisc.Tpo -c -o libracoon_la-sockmisc.lo `test -f 'sockmisc.c' || echo '$(srcdir)/'`sockmisc.c
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libracoon_la-sockmisc.Tpo $(DEPDIR)/libracoon_la-sockmisc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='sockmisc.c' object='libracoon_la-sockmisc.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-sockmisc.lo `test -f 'sockmisc.c' || echo '$(srcdir)/'`sockmisc.c
-
-libracoon_la-misc.lo: misc.c
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -MT libracoon_la-misc.lo -MD -MP -MF $(DEPDIR)/libracoon_la-misc.Tpo -c -o libracoon_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libracoon_la-misc.Tpo $(DEPDIR)/libracoon_la-misc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='misc.c' object='libracoon_la-misc.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libracoon_la_CFLAGS) $(CFLAGS) -c -o libracoon_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
-
 sha2.obj: missing/crypto/sha2/sha2.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2.obj -MD -MP -MF $(DEPDIR)/sha2.Tpo -c -o sha2.obj `if test -f 'missing/crypto/sha2/sha2.c'; then $(CYGPATH_W) 'missing/crypto/sha2/sha2.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/sha2/sha2.c'; fi`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/sha2.Tpo $(DEPDIR)/sha2.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/sha2.Tpo $(DEPDIR)/sha2.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='missing/crypto/sha2/sha2.c' object='sha2.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2.obj `if test -f 'missing/crypto/sha2/sha2.c'; then $(CYGPATH_W) 'missing/crypto/sha2/sha2.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/sha2/sha2.c'; fi`
 
 rijndael-api-fst.obj: missing/crypto/rijndael/rijndael-api-fst.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rijndael-api-fst.obj -MD -MP -MF $(DEPDIR)/rijndael-api-fst.Tpo -c -o rijndael-api-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-api-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-api-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c'; fi`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/rijndael-api-fst.Tpo $(DEPDIR)/rijndael-api-fst.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/rijndael-api-fst.Tpo $(DEPDIR)/rijndael-api-fst.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='missing/crypto/rijndael/rijndael-api-fst.c' object='rijndael-api-fst.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rijndael-api-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-api-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-api-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c'; fi`
 
 rijndael-alg-fst.obj: missing/crypto/rijndael/rijndael-alg-fst.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rijndael-alg-fst.obj -MD -MP -MF $(DEPDIR)/rijndael-alg-fst.Tpo -c -o rijndael-alg-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-alg-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-alg-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c'; fi`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/rijndael-alg-fst.Tpo $(DEPDIR)/rijndael-alg-fst.Po
+@am__fastdepCC_TRUE@	mv -f $(DEPDIR)/rijndael-alg-fst.Tpo $(DEPDIR)/rijndael-alg-fst.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='missing/crypto/rijndael/rijndael-alg-fst.c' object='rijndael-alg-fst.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rijndael-alg-fst.obj `if test -f 'missing/crypto/rijndael/rijndael-alg-fst.c'; then $(CYGPATH_W) 'missing/crypto/rijndael/rijndael-alg-fst.c'; else $(CYGPATH_W) '$(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c'; fi`
@@ -670,108 +592,127 @@
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-man5: $(man5_MANS)
+install-man5: $(man5_MANS) $(man_MANS)
 	@$(NORMAL_INSTALL)
 	test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)"
-	@list='$(man5_MANS)'; test -n "$(man5dir)" || exit 0; \
-	{ for i in $$list; do echo "$$i"; done; \
-	} | while read p; do \
-	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; echo "$$p"; \
-	done | \
-	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
-	sed 'N;N;s,\n, ,g' | { \
-	list=; while read file base inst; do \
-	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
-	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
-	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
-	  fi; \
+	@list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.5*) list="$$list $$i" ;; \
+	  esac; \
 	done; \
-	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
-	while read files; do \
-	  test -z "$$files" || { \
-	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
-	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
-	done; }
-
+	for i in $$list; do \
+	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+	  else file=$$i; fi; \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    5*) ;; \
+	    *) ext='5' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+	  $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \
+	done
 uninstall-man5:
 	@$(NORMAL_UNINSTALL)
-	@list='$(man5_MANS)'; test -n "$(man5dir)" || exit 0; \
-	files=`{ for i in $$list; do echo "$$i"; done; \
-	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
-	test -z "$$files" || { \
-	  echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \
-	  cd "$(DESTDIR)$(man5dir)" && rm -f $$files; }
-install-man8: $(man8_MANS)
+	@list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.5*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    5*) ;; \
+	    *) ext='5' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \
+	  rm -f "$(DESTDIR)$(man5dir)/$$inst"; \
+	done
+install-man8: $(man8_MANS) $(man_MANS)
 	@$(NORMAL_INSTALL)
 	test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
-	@list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
-	{ for i in $$list; do echo "$$i"; done; \
-	} | while read p; do \
-	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; echo "$$p"; \
-	done | \
-	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
-	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
-	sed 'N;N;s,\n, ,g' | { \
-	list=; while read file base inst; do \
-	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
-	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
-	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
-	  fi; \
+	@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.8*) list="$$list $$i" ;; \
+	  esac; \
 	done; \
-	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
-	while read files; do \
-	  test -z "$$files" || { \
-	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
-	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
-	done; }
-
+	for i in $$list; do \
+	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+	  else file=$$i; fi; \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    8*) ;; \
+	    *) ext='8' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+	  $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+	done
 uninstall-man8:
 	@$(NORMAL_UNINSTALL)
-	@list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
-	files=`{ for i in $$list; do echo "$$i"; done; \
-	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
-	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
-	test -z "$$files" || { \
-	  echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \
-	  cd "$(DESTDIR)$(man8dir)" && rm -f $$files; }
+	@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.8*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    8*) ;; \
+	    *) ext='8' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+	  rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+	done
 install-include_racoonHEADERS: $(include_racoon_HEADERS)
 	@$(NORMAL_INSTALL)
 	test -z "$(include_racoondir)" || $(MKDIR_P) "$(DESTDIR)$(include_racoondir)"
-	@list='$(include_racoon_HEADERS)'; test -n "$(include_racoondir)" || list=; \
-	for p in $$list; do \
+	@list='$(include_racoon_HEADERS)'; for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_racoondir)'"; \
-	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_racoondir)" || exit $$?; \
+	  f=$(am__strip_dir) \
+	  echo " $(include_racoonHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(include_racoondir)/$$f'"; \
+	  $(include_racoonHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(include_racoondir)/$$f"; \
 	done
 
 uninstall-include_racoonHEADERS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(include_racoon_HEADERS)'; test -n "$(include_racoondir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(include_racoondir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(include_racoondir)" && rm -f $$files
+	@list='$(include_racoon_HEADERS)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(include_racoondir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(include_racoondir)/$$f"; \
+	done
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
 	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
 TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
-	set x; \
+	tags=; \
 	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
@@ -779,43 +720,37 @@
 	  done | \
 	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
 	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
 	fi
 ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
+	tags=; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
 	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
 	      END { if (nonempty) { for (i in files) print i; }; }'`; \
-	test -z "$(CTAGS_ARGS)$$unique" \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
+	     $$tags $$unique
 
 GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 check-TESTS: $(TESTS)
-	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[	 ]'; \
 	srcdir=$(srcdir); export srcdir; \
 	list=' $(TESTS) '; \
-	$(am__tty_colors); \
 	if test -n "$$list"; then \
 	  for tst in $$list; do \
 	    if test -f ./$$tst; then dir=./; \
@@ -824,63 +759,49 @@
 	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
 	      all=`expr $$all + 1`; \
 	      case " $(XFAIL_TESTS) " in \
-	      *[\ \	]$$tst[\ \	]*) \
+	      *$$ws$$tst$$ws*) \
 		xpass=`expr $$xpass + 1`; \
 		failed=`expr $$failed + 1`; \
-		col=$$red; res=XPASS; \
+		echo "XPASS: $$tst"; \
 	      ;; \
 	      *) \
-		col=$$grn; res=PASS; \
+		echo "PASS: $$tst"; \
 	      ;; \
 	      esac; \
 	    elif test $$? -ne 77; then \
 	      all=`expr $$all + 1`; \
 	      case " $(XFAIL_TESTS) " in \
-	      *[\ \	]$$tst[\ \	]*) \
+	      *$$ws$$tst$$ws*) \
 		xfail=`expr $$xfail + 1`; \
-		col=$$lgn; res=XFAIL; \
+		echo "XFAIL: $$tst"; \
 	      ;; \
 	      *) \
 		failed=`expr $$failed + 1`; \
-		col=$$red; res=FAIL; \
+		echo "FAIL: $$tst"; \
 	      ;; \
 	      esac; \
 	    else \
 	      skip=`expr $$skip + 1`; \
-	      col=$$blu; res=SKIP; \
+	      echo "SKIP: $$tst"; \
 	    fi; \
-	    echo "$${col}$$res$${std}: $$tst"; \
 	  done; \
-	  if test "$$all" -eq 1; then \
-	    tests="test"; \
-	    All=""; \
-	  else \
-	    tests="tests"; \
-	    All="All "; \
-	  fi; \
 	  if test "$$failed" -eq 0; then \
 	    if test "$$xfail" -eq 0; then \
-	      banner="$$All$$all $$tests passed"; \
+	      banner="All $$all tests passed"; \
 	    else \
-	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
-	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	      banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
 	    fi; \
 	  else \
 	    if test "$$xpass" -eq 0; then \
-	      banner="$$failed of $$all $$tests failed"; \
+	      banner="$$failed of $$all tests failed"; \
 	    else \
-	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
-	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	      banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
 	    fi; \
 	  fi; \
 	  dashes="$$banner"; \
 	  skipped=""; \
 	  if test "$$skip" -ne 0; then \
-	    if test "$$skip" -eq 1; then \
-	      skipped="($$skip test was not run)"; \
-	    else \
-	      skipped="($$skip tests were not run)"; \
-	    fi; \
+	    skipped="($$skip tests were not run)"; \
 	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
 	      dashes="$$skipped"; \
 	  fi; \
@@ -891,32 +812,15 @@
 	      dashes="$$report"; \
 	  fi; \
 	  dashes=`echo "$$dashes" | sed s/./=/g`; \
-	  if test "$$failed" -eq 0; then \
-	    echo "$$grn$$dashes"; \
-	  else \
-	    echo "$$red$$dashes"; \
-	  fi; \
+	  echo "$$dashes"; \
 	  echo "$$banner"; \
 	  test -z "$$skipped" || echo "$$skipped"; \
 	  test -z "$$report" || echo "$$report"; \
-	  echo "$$dashes$$std"; \
+	  echo "$$dashes"; \
 	  test "$$failed" -eq 0; \
 	else :; fi
 
 distdir: $(DISTFILES)
-	@list='$(MANS)'; if test -n "$$list"; then \
-	  list=`for p in $$list; do \
-	    if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
-	    if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
-	  if test -n "$$list" && \
-	    grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
-	    echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
-	    grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/         /' >&2; \
-	    echo "       to fix them, install help2man, remove and regenerate the man pages;" >&2; \
-	    echo "       typically \`make maintainer-clean' will remove them" >&2; \
-	    exit 1; \
-	  else :; fi; \
-	else :; fi
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	list='$(DISTFILES)'; \
@@ -932,17 +836,13 @@
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
 	  if test -d $$d/$$file; then \
 	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
 	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
 	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
 	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
 	    || exit 1; \
 	  fi; \
 	done
@@ -976,7 +876,6 @@
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -1005,8 +904,6 @@
 
 html: html-am
 
-html-am:
-
 info: info-am
 
 info-am:
@@ -1015,29 +912,19 @@
 
 install-dvi: install-dvi-am
 
-install-dvi-am:
-
 install-exec-am: install-exec-local install-libLTLIBRARIES \
 	install-sbinPROGRAMS
 
 install-html: install-html-am
 
-install-html-am:
-
 install-info: install-info-am
 
-install-info-am:
-
 install-man: install-man5 install-man8
 
 install-pdf: install-pdf-am
 
-install-pdf-am:
-
 install-ps: install-ps-am
 
-install-ps-am:
-
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
@@ -1063,7 +950,7 @@
 
 uninstall-man: uninstall-man5 uninstall-man8
 
-.MAKE: all check check-am install install-am install-strip
+.MAKE: install-am install-strip
 
 .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
 	clean-generic clean-libLTLIBRARIES clean-libtool \
@@ -1108,7 +995,6 @@
 	$(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c
 sha2.o: $(srcdir)/missing/crypto/sha2/sha2.c
 	$(COMPILE) -c $(srcdir)/missing/crypto/sha2/$*.c
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/src/racoon/admin.c b/src/racoon/admin.c
index b0aad88..b56dd2c 100644
--- a/src/racoon/admin.c
+++ b/src/racoon/admin.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: admin.c,v 1.38 2010/12/08 07:38:35 tteras Exp $	*/
+/*	$NetBSD: admin.c,v 1.17.6.3 2009/04/20 13:32:57 tteras Exp $	*/
 
 /* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -76,7 +76,6 @@
 #include "evt.h"
 #include "pfkey.h"
 #include "ipsec_doi.h"
-#include "policy.h"
 #include "admin.h"
 #include "admin_var.h"
 #include "isakmp_inf.h"
@@ -94,12 +93,10 @@
 
 static struct sockaddr_un sunaddr;
 static int admin_process __P((int, char *));
-static int admin_reply __P((int, struct admin_com *, int, vchar_t *));
+static int admin_reply __P((int, struct admin_com *, vchar_t *));
 
-static int
-admin_handler(ctx, fd)
-	void *ctx;
-	int fd;
+int
+admin_handler()
 {
 	int so2;
 	struct sockaddr_storage from;
@@ -115,7 +112,6 @@
 			strerror(errno));
 		return -1;
 	}
-	close_on_exec(so2);
 
 	/* get buffer length */
 	while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) {
@@ -151,30 +147,22 @@
 		goto end;
 	}
 
-	error = admin_process(so2, combuf);
-
-end:
-	if (error == -2) {
-		plog(LLV_DEBUG, LOCATION, NULL,
-			"[%d] admin connection established\n", so2);
-	} else {
-		(void)close(so2);
+	if (com.ac_cmd == ADMIN_RELOAD_CONF) {
+		/* reload does not work at all! */
+		signal_handler(SIGHUP);
+		goto end;
 	}
 
+	error = admin_process(so2, combuf);
+
+    end:
+	(void)close(so2);
 	if (combuf)
 		racoon_free(combuf);
 
 	return error;
 }
 
-static int admin_ph1_delete_sa(struct ph1handle *iph1, void *arg)
-{
-	if (iph1->status >= PHASE1ST_ESTABLISHED)
-		isakmp_info_send_d1(iph1);
-	purge_remote(iph1);
-	return 0;
-}
-
 /*
  * main child's process.
  */
@@ -188,140 +176,131 @@
 	vchar_t *id = NULL;
 	vchar_t *key = NULL;
 	int idtype = 0;
-	int error = 0, l_ac_errno = 0;
-	struct evt_listener_list *event_list = NULL;
+	int error = -1;
 
-	if (com->ac_cmd & ADMIN_FLAG_VERSION)
-		com->ac_cmd &= ~ADMIN_FLAG_VERSION;
-	else
-		com->ac_version = 0;
+	com->ac_errno = 0;
 
 	switch (com->ac_cmd) {
 	case ADMIN_RELOAD_CONF:
-		signal_handler(SIGHUP);
-		break;
+		/* don't entered because of proccessing it in other place. */
+		plog(LLV_ERROR, LOCATION, NULL, "should never reach here\n");
+		goto out;
 
-	case ADMIN_SHOW_SCHED: {
+	case ADMIN_SHOW_SCHED:
+	{
 		caddr_t p = NULL;
 		int len;
 
-		if (sched_dump(&p, &len) != -1) {
-			buf = vmalloc(len);
-			if (buf != NULL)
-				memcpy(buf->v, p, len);
-			else
-				l_ac_errno = ENOMEM;
-			racoon_free(p);
-		} else
-			l_ac_errno = ENOMEM;
+		com->ac_errno = -1;
+
+		if (sched_dump(&p, &len) == -1)
+			goto out2;
+
+		if ((buf = vmalloc(len)) == NULL)
+			goto out2;
+
+		memcpy(buf->v, p, len);
+
+		com->ac_errno = 0;
+out2:
+		racoon_free(p);
 		break;
 	}
 
 	case ADMIN_SHOW_EVT:
-		if (com->ac_version == 0) {
-			buf = evt_dump();
-			l_ac_errno = 0;
-		}
+		/* It's not really an error, don't force racoonctl to quit */
+		if ((buf = evt_dump()) == NULL)
+			com->ac_errno = 0; 
 		break;
 
 	case ADMIN_SHOW_SA:
-		switch (com->ac_proto) {
-		case ADMIN_PROTO_ISAKMP:
-			buf = dumpph1();
-			if (buf == NULL)
-				l_ac_errno = ENOMEM;
-			break;
-		case ADMIN_PROTO_IPSEC:
-		case ADMIN_PROTO_AH:
-		case ADMIN_PROTO_ESP: {
-			u_int p;
-			p = admin2pfkey_proto(com->ac_proto);
-			if (p != -1) {
-				buf = pfkey_dump_sadb(p);
-				if (buf == NULL)
-					l_ac_errno = ENOMEM;
-			} else
-				l_ac_errno = EINVAL;
-			break;
-		}
-		case ADMIN_PROTO_INTERNAL:
-		default:
-			l_ac_errno = ENOTSUP;
-			break;
-		}
-		break;
-
-	case ADMIN_GET_SA_CERT: {
-		struct admin_com_indexes *ndx;
-		struct sockaddr *src, *dst;
-		struct ph1handle *iph1;
-
-		ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com));
-		src = (struct sockaddr *) &ndx->src;
-		dst = (struct sockaddr *) &ndx->dst;
-
-		if (com->ac_proto != ADMIN_PROTO_ISAKMP) {
-			l_ac_errno = ENOTSUP;
-			break;
-		}
-
-		iph1 = getph1byaddr(src, dst, 0);
-		if (iph1 == NULL) {
-			l_ac_errno = ENOENT;
-			break;
-		}
-
-		if (iph1->cert_p != NULL) {
-			vchar_t tmp;
-			tmp.v = iph1->cert_p->v + 1;
-			tmp.l = iph1->cert_p->l - 1;
-			buf = vdup(&tmp);
-		}
-		break;
-	}
-
 	case ADMIN_FLUSH_SA:
+	    {
 		switch (com->ac_proto) {
 		case ADMIN_PROTO_ISAKMP:
-			flushph1();
+			switch (com->ac_cmd) {
+			case ADMIN_SHOW_SA:
+				buf = dumpph1();
+				if (buf == NULL)
+					com->ac_errno = -1;
+				break;
+			case ADMIN_FLUSH_SA:
+				flushph1();
+				break;
+			}
 			break;
 		case ADMIN_PROTO_IPSEC:
 		case ADMIN_PROTO_AH:
 		case ADMIN_PROTO_ESP:
-			pfkey_flush_sadb(com->ac_proto);
+			switch (com->ac_cmd) {
+			case ADMIN_SHOW_SA:
+			    {
+				u_int p;
+				p = admin2pfkey_proto(com->ac_proto);
+				if (p == -1)
+					goto out;
+				buf = pfkey_dump_sadb(p);
+				if (buf == NULL)
+					com->ac_errno = -1;
+			    }
+				break;
+			case ADMIN_FLUSH_SA:
+				pfkey_flush_sadb(com->ac_proto);
+				break;
+			}
 			break;
+
 		case ADMIN_PROTO_INTERNAL:
-			/*XXX flushph2();*/
-		default:
-			l_ac_errno = ENOTSUP;
+			switch (com->ac_cmd) {
+			case ADMIN_SHOW_SA:
+				buf = NULL; /*XXX dumpph2(&error);*/
+				if (buf == NULL)
+					com->ac_errno = error;
+				break;
+			case ADMIN_FLUSH_SA:
+				/*XXX flushph2();*/
+				com->ac_errno = 0;
+				break;
+			}
 			break;
+
+		default:
+			/* ignore */
+			com->ac_errno = -1;
 		}
+	    }
 		break;
 
 	case ADMIN_DELETE_SA: {
+		struct ph1handle *iph1;
+		struct sockaddr *dst;
+		struct sockaddr *src;
 		char *loc, *rem;
-		struct ph1selector sel;
 
-		memset(&sel, 0, sizeof(sel));
-		sel.local = (struct sockaddr *)
+		src = (struct sockaddr *)
 			&((struct admin_com_indexes *)
 			    ((caddr_t)com + sizeof(*com)))->src;
-		sel.remote = (struct sockaddr *)
+		dst = (struct sockaddr *)
 			&((struct admin_com_indexes *)
 			    ((caddr_t)com + sizeof(*com)))->dst;
 
-		loc = racoon_strdup(saddr2str(sel.local));
-		rem = racoon_strdup(saddr2str(sel.remote));
+		loc = racoon_strdup(saddrwop2str(src));
+		rem = racoon_strdup(saddrwop2str(dst));
 		STRDUP_FATAL(loc);
 		STRDUP_FATAL(rem);
 
-		plog(LLV_INFO, LOCATION, NULL,
-		     "admin delete-sa %s %s\n", loc, rem);
-		enumph1(&sel, admin_ph1_delete_sa, NULL);
-		remcontacted(sel.remote);
+		if ((iph1 = getph1byaddrwop(src, dst)) == NULL) {
+			plog(LLV_ERROR, LOCATION, NULL, 
+			    "phase 1 for %s -> %s not found\n", loc, rem);
+		} else {
+			if (iph1->status == PHASE1ST_ESTABLISHED)
+				isakmp_info_send_d1(iph1);
+			purge_remote(iph1);
+		}
 
 		racoon_free(loc);
 		racoon_free(rem);
+
 		break;
 	}
 
@@ -329,7 +308,7 @@
 	case ADMIN_LOGOUT_USER: {
 		struct ph1handle *iph1;
 		char user[LOGINLEN+1];
-		int found = 0, len = com->ac_len - sizeof(*com);
+		int found = 0, len = com->ac_len - sizeof(com);
 
 		if (len > LOGINLEN) {
 			plog(LLV_ERROR, LOCATION, NULL,
@@ -341,7 +320,7 @@
 		user[len] = 0;
 
 		found = purgeph1bylogin(user);
-		plog(LLV_INFO, LOCATION, NULL,
+		plog(LLV_INFO, LOCATION, NULL, 
 		    "deleted %d SA for user \"%s\"\n", found, user);
 
 		break;
@@ -360,21 +339,22 @@
 		rem = racoon_strdup(saddrwop2str(dst));
 		STRDUP_FATAL(rem);
 
-		plog(LLV_INFO, LOCATION, NULL,
+		plog(LLV_INFO, LOCATION, NULL, 
 		    "Flushing all SAs for peer %s\n", rem);
 
-		while ((iph1 = getph1bydstaddr(dst)) != NULL) {
+		while ((iph1 = getph1bydstaddrwop(dst)) != NULL) {
 			loc = racoon_strdup(saddrwop2str(iph1->local));
 			STRDUP_FATAL(loc);
 
-			if (iph1->status >= PHASE1ST_ESTABLISHED)
+			if (iph1->status == PHASE1ST_ESTABLISHED)
 				isakmp_info_send_d1(iph1);
 			purge_remote(iph1);
 
 			racoon_free(loc);
 		}
-
+		
 		racoon_free(rem);
+
 		break;
 	}
 
@@ -382,15 +362,17 @@
 		struct admin_com_psk *acp;
 		char *data;
 
+		com->ac_cmd = ADMIN_ESTABLISH_SA;
+
 		acp = (struct admin_com_psk *)
-		    ((char *)com + sizeof(*com) +
+		    ((char *)com + sizeof(*com) + 
 		    sizeof(struct admin_com_indexes));
 
 		idtype = acp->id_type;
 
 		if ((id = vmalloc(acp->id_len)) == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			    "cannot allocate memory: %s\n",
+			    "cannot allocate memory: %s\n", 
 			    strerror(errno));
 			break;
 		}
@@ -399,7 +381,7 @@
 
 		if ((key = vmalloc(acp->key_len)) == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			    "cannot allocate memory: %s\n",
+			    "cannot allocate memory: %s\n", 
 			    strerror(errno));
 			vfree(id);
 			id = NULL;
@@ -409,57 +391,56 @@
 		memcpy(key->v, data, key->l);
 	}
 	/* FALLTHROUGH */
-	case ADMIN_ESTABLISH_SA: {
-		struct admin_com_indexes *ndx;
+	case ADMIN_ESTABLISH_SA:
+	    {
 		struct sockaddr *dst;
 		struct sockaddr *src;
-		char *name = NULL;
-
-		ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com));
-		src = (struct sockaddr *) &ndx->src;
-		dst = (struct sockaddr *) &ndx->dst;
-
-		if (com->ac_cmd == ADMIN_ESTABLISH_SA &&
-		    com->ac_len > sizeof(*com) + sizeof(*ndx))
-			name = (char *) ((caddr_t) ndx + sizeof(*ndx));
+		src = (struct sockaddr *)
+			&((struct admin_com_indexes *)
+			    ((caddr_t)com + sizeof(*com)))->src;
+		dst = (struct sockaddr *)
+			&((struct admin_com_indexes *)
+			    ((caddr_t)com + sizeof(*com)))->dst;
 
 		switch (com->ac_proto) {
 		case ADMIN_PROTO_ISAKMP: {
-			struct ph1handle *ph1;
 			struct remoteconf *rmconf;
+			struct sockaddr *remote = NULL;
+			struct sockaddr *local = NULL;
 			u_int16_t port;
 
-			l_ac_errno = -1;
-
-			/* connected already? */
-			ph1 = getph1byaddr(src, dst, 0);
-			if (ph1 != NULL) {
-				event_list = &ph1->evt_listeners;
-				if (ph1->status == PHASE1ST_ESTABLISHED)
-					l_ac_errno = EEXIST;
-				else
-					l_ac_errno = 0;
-				break;
-			}
+			com->ac_errno = -1;
 
 			/* search appropreate configuration */
-			if (name == NULL)
-				rmconf = getrmconf(dst, 0);
-			else
-				rmconf = getrmconf_by_name(name);
+			rmconf = getrmconf(dst);
 			if (rmconf == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
 					"no configuration found "
 					"for %s\n", saddrwop2str(dst));
-				break;
+				goto out1;
 			}
 
+			/* get remote IP address and port number. */
+			if ((remote = dupsaddr(dst)) == NULL)
+				goto out1;
+
+			port = extract_port(rmconf->remote);
+			if (set_port(remote, port) == NULL)
+				goto out1;
+
+			/* get local address */
+			if ((local = dupsaddr(src)) == NULL)
+				goto out1;
+
+			port = getmyaddrsport(local);
+			if (set_port(local, port) == NULL)
+				goto out1;
+
 #ifdef ENABLE_HYBRID
-			/* XXX This overwrites rmconf information globally. */
 			/* Set the id and key */
 			if (id && key) {
 				if (xauth_rmconf_used(&rmconf->xauth) == -1)
-					break;
+					goto out1;
 
 				if (rmconf->xauth->login != NULL) {
 					vfree(rmconf->xauth->login);
@@ -474,145 +455,43 @@
 				rmconf->xauth->pass = key;
 			}
 #endif
-
+ 
 			plog(LLV_INFO, LOCATION, NULL,
 				"accept a request to establish IKE-SA: "
-				"%s\n", saddrwop2str(dst));
+				"%s\n", saddrwop2str(remote));
 
 			/* begin ident mode */
-			ph1 = isakmp_ph1begin_i(rmconf, dst, src);
-			if (ph1 == NULL)
-				break;
+			if (isakmp_ph1begin_i(rmconf, remote, local) < 0)
+				goto out1;
 
-			event_list = &ph1->evt_listeners;
-			l_ac_errno = 0;
+			com->ac_errno = 0;
+out1:
+			if (local != NULL)
+				racoon_free(local);
+			if (remote != NULL)
+				racoon_free(remote);
 			break;
 		}
 		case ADMIN_PROTO_AH:
-		case ADMIN_PROTO_ESP: {
-			struct ph2handle *iph2;
-			struct secpolicy *sp_out = NULL, *sp_in = NULL;
-			struct policyindex spidx;
-
-			l_ac_errno = -1;
-
-			/* got outbound policy */
-			memset(&spidx, 0, sizeof(spidx));
-			spidx.dir = IPSEC_DIR_OUTBOUND;
-			memcpy(&spidx.src, src, sizeof(spidx.src));
-			memcpy(&spidx.dst, dst, sizeof(spidx.dst));
-			spidx.prefs = ndx->prefs;
-			spidx.prefd = ndx->prefd;
-			spidx.ul_proto = ndx->ul_proto;
-
-			sp_out = getsp_r(&spidx);
-			if (sp_out) {
-				plog(LLV_DEBUG, LOCATION, NULL,
-					"suitable outbound SP found: %s.\n",
-					spidx2str(&sp_out->spidx));
-			} else {
-				l_ac_errno = ENOENT;
-				plog(LLV_NOTIFY, LOCATION, NULL,
-					"no outbound policy found: %s\n",
-					spidx2str(&spidx));
-				break;
-			}
-
-			iph2 = getph2byid(src, dst, sp_out->id);
-			if (iph2 != NULL) {
-				event_list = &iph2->evt_listeners;
-				if (iph2->status == PHASE2ST_ESTABLISHED)
-					l_ac_errno = EEXIST;
-				else
-					l_ac_errno = 0;
-				break;
-			}
-
-			/* get inbound policy */
-			memset(&spidx, 0, sizeof(spidx));
-			spidx.dir = IPSEC_DIR_INBOUND;
-			memcpy(&spidx.src, dst, sizeof(spidx.src));
-			memcpy(&spidx.dst, src, sizeof(spidx.dst));
-			spidx.prefs = ndx->prefd;
-			spidx.prefd = ndx->prefs;
-			spidx.ul_proto = ndx->ul_proto;
-
-			sp_in = getsp_r(&spidx);
-			if (sp_in) {
-				plog(LLV_DEBUG, LOCATION, NULL,
-					"suitable inbound SP found: %s.\n",
-					spidx2str(&sp_in->spidx));
-			} else {
-				l_ac_errno = ENOENT;
-				plog(LLV_NOTIFY, LOCATION, NULL,
-					"no inbound policy found: %s\n",
-				spidx2str(&spidx));
-				break;
-			}
-
-			/* allocate a phase 2 */
-			iph2 = newph2();
-			if (iph2 == NULL) {
-				plog(LLV_ERROR, LOCATION, NULL,
-					"failed to allocate phase2 entry.\n");
-				break;
-			}
-			iph2->side = INITIATOR;
-			iph2->satype = admin2pfkey_proto(com->ac_proto);
-			iph2->spid = sp_out->id;
-			iph2->seq = pk_getseq();
-			iph2->status = PHASE2ST_STATUS2;
-
-			/* set end addresses of SA */
-			iph2->sa_dst = dupsaddr(dst);
-			iph2->sa_src = dupsaddr(src);
-			iph2->dst = dupsaddr(dst);
-			iph2->src = dupsaddr(src);
-			if (iph2->sa_src == NULL || iph2->sa_dst == NULL ||
-			    iph2->dst == NULL || iph2->src == NULL) {
-				delph2(iph2);
-				break;
-			}
-			set_port(iph2->dst, 0);
-			set_port(iph2->src, 0);
-
-			if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) {
-				delph2(iph2);
-				break;
-			}
-
-			insph2(iph2);
-			if (isakmp_post_acquire(iph2, NULL, FALSE) < 0) {
-				remph2(iph2);
-				delph2(iph2);
-				break;
-			}
-
-			event_list = &iph2->evt_listeners;
-			l_ac_errno = 0;
+		case ADMIN_PROTO_ESP:
 			break;
-		}
 		default:
 			/* ignore */
-			l_ac_errno = ENOTSUP;
+			com->ac_errno = -1;
 		}
+	    }
 		break;
-	}
 
 	default:
 		plog(LLV_ERROR, LOCATION, NULL,
 			"invalid command: %d\n", com->ac_cmd);
-		l_ac_errno = ENOTSUP;
+		com->ac_errno = -1;
 	}
 
-	if ((error = admin_reply(so2, com, l_ac_errno, buf)) != 0)
+	if ((error = admin_reply(so2, com, buf)) != 0)
 		goto out;
 
-	/* start pushing events if so requested */
-	if ((l_ac_errno == 0) &&
-	    (com->ac_version >= 1) &&
-	    (com->ac_cmd == ADMIN_SHOW_EVT || event_list != NULL))
-		error = evt_subscribe(event_list, so2);
+	error = 0;
 out:
 	if (buf != NULL)
 		vfree(buf);
@@ -621,13 +500,12 @@
 }
 
 static int
-admin_reply(so, req, l_ac_errno, buf)
-	int so, l_ac_errno;
-	struct admin_com *req;
+admin_reply(so, combuf, buf)
+	int so;
+	struct admin_com *combuf;
 	vchar_t *buf;
 {
 	int tlen;
-	struct admin_com *combuf;
 	char *retbuf = NULL;
 
 	if (buf != NULL)
@@ -642,17 +520,8 @@
 		return -1;
 	}
 
-	combuf = (struct admin_com *) retbuf;
-	combuf->ac_len = (u_int16_t) tlen;
-	combuf->ac_cmd = req->ac_cmd & ~ADMIN_FLAG_VERSION;
-	if (tlen != (u_int32_t) combuf->ac_len &&
-	    l_ac_errno == 0) {
-		combuf->ac_len_high = tlen >> 16;
-		combuf->ac_cmd |= ADMIN_FLAG_LONG_REPLY;
-	} else {
-		combuf->ac_errno = l_ac_errno;
-	}
-	combuf->ac_proto = req->ac_proto;
+	memcpy(retbuf, combuf, sizeof(*combuf));
+	((struct admin_com *)retbuf)->ac_len = tlen;
 
 	if (buf != NULL)
 		memcpy(retbuf + sizeof(*combuf), buf->v, buf->l);
@@ -708,7 +577,6 @@
 			"socket: %s\n", strerror(errno));
 		return -1;
 	}
-	close_on_exec(lcconf->sock_admin);
 
 	unlink(sunaddr.sun_path);
 	if (bind(lcconf->sock_admin, (struct sockaddr *)&sunaddr,
@@ -721,17 +589,17 @@
 	}
 
 	if (chown(sunaddr.sun_path, adminsock_owner, adminsock_group) != 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		    "chown(%s, %d, %d): %s\n",
-		    sunaddr.sun_path, adminsock_owner,
+		plog(LLV_ERROR, LOCATION, NULL, 
+		    "chown(%s, %d, %d): %s\n", 
+		    sunaddr.sun_path, adminsock_owner, 
 		    adminsock_group, strerror(errno));
 		(void)close(lcconf->sock_admin);
 		return -1;
 	}
 
 	if (chmod(sunaddr.sun_path, adminsock_mode) != 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		    "chmod(%s, 0%03o): %s\n",
+		plog(LLV_ERROR, LOCATION, NULL, 
+		    "chmod(%s, 0%03o): %s\n", 
 		    sunaddr.sun_path, adminsock_mode, strerror(errno));
 		(void)close(lcconf->sock_admin);
 		return -1;
@@ -744,10 +612,8 @@
 		(void)close(lcconf->sock_admin);
 		return -1;
 	}
-
-	monitor_fd(lcconf->sock_admin, admin_handler, NULL, 0);
 	plog(LLV_DEBUG, LOCATION, NULL,
-	     "open %s as racoon management.\n", sunaddr.sun_path);
+		"open %s as racoon management.\n", sunaddr.sun_path);
 
 	return 0;
 }
@@ -755,9 +621,8 @@
 int
 admin_close()
 {
-	unmonitor_fd(lcconf->sock_admin);
 	close(lcconf->sock_admin);
 	return 0;
 }
-
 #endif
+
diff --git a/src/racoon/admin.h b/src/racoon/admin.h
index 8cb9382..cbc19e8 100644
--- a/src/racoon/admin.h
+++ b/src/racoon/admin.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: admin.h,v 1.8 2010/11/12 09:08:26 tteras Exp $	*/
+/*	$NetBSD: admin.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: admin.h,v 1.11 2005/06/19 22:37:47 manubsd Exp */
 
@@ -46,22 +46,9 @@
 struct admin_com {
 	u_int16_t ac_len;	/* total packet length including data */
 	u_int16_t ac_cmd;
-	union {
-		int16_t ac_un_errno;
-		uint16_t ac_un_version;
-		uint16_t ac_un_len_high;
-	} u;
+	int16_t ac_errno;
 	u_int16_t ac_proto;
 };
-#define ac_errno u.ac_un_errno
-#define ac_version u.ac_un_version
-#define ac_len_high u.ac_un_len_high
-
-/*
- * Version field in request is valid.
- */
-#define ADMIN_FLAG_VERSION	0x8000
-#define ADMIN_FLAG_LONG_REPLY	0x8000
 
 /*
  * No data follows as the data.
@@ -85,8 +72,6 @@
 #define ADMIN_ESTABLISH_SA	0x0202
 #define ADMIN_DELETE_ALL_SA_DST	0x0204	/* All SA for a given peer */
 
-#define ADMIN_GET_SA_CERT	0x0206
-
 /*
  * The admin_com_indexes and admin_com_psk follow, see below.
  */
diff --git a/src/racoon/admin_var.h b/src/racoon/admin_var.h
index f4471a3..6d7ba81 100644
--- a/src/racoon/admin_var.h
+++ b/src/racoon/admin_var.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: admin_var.h,v 1.5 2008/12/23 14:03:12 tteras Exp $	*/
+/*	$NetBSD: admin_var.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: admin_var.h,v 1.7 2004/12/30 00:08:30 manubsd Exp */
 
@@ -34,6 +34,7 @@
 #ifndef _ADMIN_VAR_H
 #define _ADMIN_VAR_H
 
+extern int admin_handler __P((void));
 extern int admin_init __P((void));
 extern int admin_close __P((void));
 
diff --git a/src/racoon/backupsa.c b/src/racoon/backupsa.c
index 82d74ca..9496000 100644
--- a/src/racoon/backupsa.c
+++ b/src/racoon/backupsa.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: backupsa.c,v 1.10 2010/04/02 15:15:00 christos Exp $	*/
+/*	$NetBSD: backupsa.c,v 1.8.4.1 2007/08/01 11:52:19 vanhu Exp $	*/
 
 /*	$KAME: backupsa.c,v 1.16 2001/12/31 20:13:40 thorpej Exp $	*/
 
@@ -452,7 +452,7 @@
 	struct tm tm;
 	time_t t;
 	char *buf = "Nov 24 18:22:48 1986 ";
-	const char *p;
+	char *p;
 
 	memset(&tm, 0, sizeof(tm));
 	p = str2tmx(buf, &tm);
@@ -460,8 +460,7 @@
 	t = mktime(&tm);
 	if (t == -1)
 		printf("mktime failed.");
-	if ((p = ctime(&t)) == NULL)
-		p = "?";
+	p = ctime(&t);
 	printf("[%s]\n", p);
 
 	exit(0);
diff --git a/src/racoon/cfparse.h b/src/racoon/cfparse.h
index bbf678a..2946b3e 100644
--- a/src/racoon/cfparse.h
+++ b/src/racoon/cfparse.h
@@ -1,23 +1,24 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
 /* Skeleton interface for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -28,11 +29,10 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -46,170 +46,161 @@
      PATH = 262,
      PATHTYPE = 263,
      INCLUDE = 264,
-     PFKEY_BUFFER = 265,
-     LOGGING = 266,
-     LOGLEV = 267,
-     PADDING = 268,
-     PAD_RANDOMIZE = 269,
-     PAD_RANDOMIZELEN = 270,
-     PAD_MAXLEN = 271,
-     PAD_STRICT = 272,
-     PAD_EXCLTAIL = 273,
-     LISTEN = 274,
-     X_ISAKMP = 275,
-     X_ISAKMP_NATT = 276,
-     X_ADMIN = 277,
-     STRICT_ADDRESS = 278,
-     ADMINSOCK = 279,
-     DISABLED = 280,
-     LDAPCFG = 281,
-     LDAP_HOST = 282,
-     LDAP_PORT = 283,
-     LDAP_PVER = 284,
-     LDAP_BASE = 285,
-     LDAP_BIND_DN = 286,
-     LDAP_BIND_PW = 287,
-     LDAP_SUBTREE = 288,
-     LDAP_ATTR_USER = 289,
-     LDAP_ATTR_ADDR = 290,
-     LDAP_ATTR_MASK = 291,
-     LDAP_ATTR_GROUP = 292,
-     LDAP_ATTR_MEMBER = 293,
-     RADCFG = 294,
-     RAD_AUTH = 295,
-     RAD_ACCT = 296,
-     RAD_TIMEOUT = 297,
-     RAD_RETRIES = 298,
-     MODECFG = 299,
-     CFG_NET4 = 300,
-     CFG_MASK4 = 301,
-     CFG_DNS4 = 302,
-     CFG_NBNS4 = 303,
-     CFG_DEFAULT_DOMAIN = 304,
-     CFG_AUTH_SOURCE = 305,
-     CFG_AUTH_GROUPS = 306,
-     CFG_SYSTEM = 307,
-     CFG_RADIUS = 308,
-     CFG_PAM = 309,
-     CFG_LDAP = 310,
-     CFG_LOCAL = 311,
-     CFG_NONE = 312,
-     CFG_GROUP_SOURCE = 313,
-     CFG_ACCOUNTING = 314,
-     CFG_CONF_SOURCE = 315,
-     CFG_MOTD = 316,
-     CFG_POOL_SIZE = 317,
-     CFG_AUTH_THROTTLE = 318,
-     CFG_SPLIT_NETWORK = 319,
-     CFG_SPLIT_LOCAL = 320,
-     CFG_SPLIT_INCLUDE = 321,
-     CFG_SPLIT_DNS = 322,
-     CFG_PFS_GROUP = 323,
-     CFG_SAVE_PASSWD = 324,
-     RETRY = 325,
-     RETRY_COUNTER = 326,
-     RETRY_INTERVAL = 327,
-     RETRY_PERSEND = 328,
-     RETRY_PHASE1 = 329,
-     RETRY_PHASE2 = 330,
-     NATT_KA = 331,
-     ALGORITHM_CLASS = 332,
-     ALGORITHMTYPE = 333,
-     STRENGTHTYPE = 334,
-     SAINFO = 335,
-     FROM = 336,
-     REMOTE = 337,
-     ANONYMOUS = 338,
-     CLIENTADDR = 339,
-     INHERIT = 340,
-     REMOTE_ADDRESS = 341,
-     EXCHANGE_MODE = 342,
-     EXCHANGETYPE = 343,
-     DOI = 344,
-     DOITYPE = 345,
-     SITUATION = 346,
-     SITUATIONTYPE = 347,
-     CERTIFICATE_TYPE = 348,
-     CERTTYPE = 349,
-     PEERS_CERTFILE = 350,
-     CA_TYPE = 351,
-     VERIFY_CERT = 352,
-     SEND_CERT = 353,
-     SEND_CR = 354,
-     MATCH_EMPTY_CR = 355,
-     IDENTIFIERTYPE = 356,
-     IDENTIFIERQUAL = 357,
-     MY_IDENTIFIER = 358,
-     PEERS_IDENTIFIER = 359,
-     VERIFY_IDENTIFIER = 360,
-     DNSSEC = 361,
-     CERT_X509 = 362,
-     CERT_PLAINRSA = 363,
-     NONCE_SIZE = 364,
-     DH_GROUP = 365,
-     KEEPALIVE = 366,
-     PASSIVE = 367,
-     INITIAL_CONTACT = 368,
-     NAT_TRAVERSAL = 369,
-     REMOTE_FORCE_LEVEL = 370,
-     PROPOSAL_CHECK = 371,
-     PROPOSAL_CHECK_LEVEL = 372,
-     GENERATE_POLICY = 373,
-     GENERATE_LEVEL = 374,
-     SUPPORT_PROXY = 375,
-     PROPOSAL = 376,
-     EXEC_PATH = 377,
-     EXEC_COMMAND = 378,
-     EXEC_SUCCESS = 379,
-     EXEC_FAILURE = 380,
-     GSS_ID = 381,
-     GSS_ID_ENC = 382,
-     GSS_ID_ENCTYPE = 383,
-     COMPLEX_BUNDLE = 384,
-     DPD = 385,
-     DPD_DELAY = 386,
-     DPD_RETRY = 387,
-     DPD_MAXFAIL = 388,
-     PH1ID = 389,
-     XAUTH_LOGIN = 390,
-     WEAK_PHASE1_CHECK = 391,
-     REKEY = 392,
-     PREFIX = 393,
-     PORT = 394,
-     PORTANY = 395,
-     UL_PROTO = 396,
-     ANY = 397,
-     IKE_FRAG = 398,
-     ESP_FRAG = 399,
-     MODE_CFG = 400,
-     PFS_GROUP = 401,
-     LIFETIME = 402,
-     LIFETYPE_TIME = 403,
-     LIFETYPE_BYTE = 404,
-     STRENGTH = 405,
-     REMOTEID = 406,
-     SCRIPT = 407,
-     PHASE1_UP = 408,
-     PHASE1_DOWN = 409,
-     PHASE1_DEAD = 410,
-     NUMBER = 411,
-     SWITCH = 412,
-     BOOLEAN = 413,
-     HEXSTRING = 414,
-     QUOTEDSTRING = 415,
-     ADDRSTRING = 416,
-     ADDRRANGE = 417,
-     UNITTYPE_BYTE = 418,
-     UNITTYPE_KBYTES = 419,
-     UNITTYPE_MBYTES = 420,
-     UNITTYPE_TBYTES = 421,
-     UNITTYPE_SEC = 422,
-     UNITTYPE_MIN = 423,
-     UNITTYPE_HOUR = 424,
-     EOS = 425,
-     BOC = 426,
-     EOC = 427,
-     COMMA = 428
+     IDENTIFIER = 265,
+     VENDORID = 266,
+     LOGGING = 267,
+     LOGLEV = 268,
+     PADDING = 269,
+     PAD_RANDOMIZE = 270,
+     PAD_RANDOMIZELEN = 271,
+     PAD_MAXLEN = 272,
+     PAD_STRICT = 273,
+     PAD_EXCLTAIL = 274,
+     LISTEN = 275,
+     X_ISAKMP = 276,
+     X_ISAKMP_NATT = 277,
+     X_ADMIN = 278,
+     STRICT_ADDRESS = 279,
+     ADMINSOCK = 280,
+     DISABLED = 281,
+     LDAPCFG = 282,
+     LDAP_HOST = 283,
+     LDAP_PORT = 284,
+     LDAP_PVER = 285,
+     LDAP_BASE = 286,
+     LDAP_BIND_DN = 287,
+     LDAP_BIND_PW = 288,
+     LDAP_SUBTREE = 289,
+     LDAP_ATTR_USER = 290,
+     LDAP_ATTR_ADDR = 291,
+     LDAP_ATTR_MASK = 292,
+     LDAP_ATTR_GROUP = 293,
+     LDAP_ATTR_MEMBER = 294,
+     MODECFG = 295,
+     CFG_NET4 = 296,
+     CFG_MASK4 = 297,
+     CFG_DNS4 = 298,
+     CFG_NBNS4 = 299,
+     CFG_DEFAULT_DOMAIN = 300,
+     CFG_AUTH_SOURCE = 301,
+     CFG_AUTH_GROUPS = 302,
+     CFG_SYSTEM = 303,
+     CFG_RADIUS = 304,
+     CFG_PAM = 305,
+     CFG_LDAP = 306,
+     CFG_LOCAL = 307,
+     CFG_NONE = 308,
+     CFG_GROUP_SOURCE = 309,
+     CFG_ACCOUNTING = 310,
+     CFG_CONF_SOURCE = 311,
+     CFG_MOTD = 312,
+     CFG_POOL_SIZE = 313,
+     CFG_AUTH_THROTTLE = 314,
+     CFG_SPLIT_NETWORK = 315,
+     CFG_SPLIT_LOCAL = 316,
+     CFG_SPLIT_INCLUDE = 317,
+     CFG_SPLIT_DNS = 318,
+     CFG_PFS_GROUP = 319,
+     CFG_SAVE_PASSWD = 320,
+     RETRY = 321,
+     RETRY_COUNTER = 322,
+     RETRY_INTERVAL = 323,
+     RETRY_PERSEND = 324,
+     RETRY_PHASE1 = 325,
+     RETRY_PHASE2 = 326,
+     NATT_KA = 327,
+     ALGORITHM_CLASS = 328,
+     ALGORITHMTYPE = 329,
+     STRENGTHTYPE = 330,
+     SAINFO = 331,
+     FROM = 332,
+     REMOTE = 333,
+     ANONYMOUS = 334,
+     INHERIT = 335,
+     EXCHANGE_MODE = 336,
+     EXCHANGETYPE = 337,
+     DOI = 338,
+     DOITYPE = 339,
+     SITUATION = 340,
+     SITUATIONTYPE = 341,
+     CERTIFICATE_TYPE = 342,
+     CERTTYPE = 343,
+     PEERS_CERTFILE = 344,
+     CA_TYPE = 345,
+     VERIFY_CERT = 346,
+     SEND_CERT = 347,
+     SEND_CR = 348,
+     IDENTIFIERTYPE = 349,
+     IDENTIFIERQUAL = 350,
+     MY_IDENTIFIER = 351,
+     PEERS_IDENTIFIER = 352,
+     VERIFY_IDENTIFIER = 353,
+     DNSSEC = 354,
+     CERT_X509 = 355,
+     CERT_PLAINRSA = 356,
+     NONCE_SIZE = 357,
+     DH_GROUP = 358,
+     KEEPALIVE = 359,
+     PASSIVE = 360,
+     INITIAL_CONTACT = 361,
+     NAT_TRAVERSAL = 362,
+     REMOTE_FORCE_LEVEL = 363,
+     PROPOSAL_CHECK = 364,
+     PROPOSAL_CHECK_LEVEL = 365,
+     GENERATE_POLICY = 366,
+     GENERATE_LEVEL = 367,
+     SUPPORT_PROXY = 368,
+     PROPOSAL = 369,
+     EXEC_PATH = 370,
+     EXEC_COMMAND = 371,
+     EXEC_SUCCESS = 372,
+     EXEC_FAILURE = 373,
+     GSS_ID = 374,
+     GSS_ID_ENC = 375,
+     GSS_ID_ENCTYPE = 376,
+     COMPLEX_BUNDLE = 377,
+     DPD = 378,
+     DPD_DELAY = 379,
+     DPD_RETRY = 380,
+     DPD_MAXFAIL = 381,
+     PH1ID = 382,
+     XAUTH_LOGIN = 383,
+     WEAK_PHASE1_CHECK = 384,
+     PREFIX = 385,
+     PORT = 386,
+     PORTANY = 387,
+     UL_PROTO = 388,
+     ANY = 389,
+     IKE_FRAG = 390,
+     ESP_FRAG = 391,
+     MODE_CFG = 392,
+     PFS_GROUP = 393,
+     LIFETIME = 394,
+     LIFETYPE_TIME = 395,
+     LIFETYPE_BYTE = 396,
+     STRENGTH = 397,
+     REMOTEID = 398,
+     SCRIPT = 399,
+     PHASE1_UP = 400,
+     PHASE1_DOWN = 401,
+     NUMBER = 402,
+     SWITCH = 403,
+     BOOLEAN = 404,
+     HEXSTRING = 405,
+     QUOTEDSTRING = 406,
+     ADDRSTRING = 407,
+     ADDRRANGE = 408,
+     UNITTYPE_BYTE = 409,
+     UNITTYPE_KBYTES = 410,
+     UNITTYPE_MBYTES = 411,
+     UNITTYPE_TBYTES = 412,
+     UNITTYPE_SEC = 413,
+     UNITTYPE_MIN = 414,
+     UNITTYPE_HOUR = 415,
+     EOS = 416,
+     BOC = 417,
+     EOC = 418,
+     COMMA = 419
    };
 #endif
 /* Tokens.  */
@@ -220,197 +211,182 @@
 #define PATH 262
 #define PATHTYPE 263
 #define INCLUDE 264
-#define PFKEY_BUFFER 265
-#define LOGGING 266
-#define LOGLEV 267
-#define PADDING 268
-#define PAD_RANDOMIZE 269
-#define PAD_RANDOMIZELEN 270
-#define PAD_MAXLEN 271
-#define PAD_STRICT 272
-#define PAD_EXCLTAIL 273
-#define LISTEN 274
-#define X_ISAKMP 275
-#define X_ISAKMP_NATT 276
-#define X_ADMIN 277
-#define STRICT_ADDRESS 278
-#define ADMINSOCK 279
-#define DISABLED 280
-#define LDAPCFG 281
-#define LDAP_HOST 282
-#define LDAP_PORT 283
-#define LDAP_PVER 284
-#define LDAP_BASE 285
-#define LDAP_BIND_DN 286
-#define LDAP_BIND_PW 287
-#define LDAP_SUBTREE 288
-#define LDAP_ATTR_USER 289
-#define LDAP_ATTR_ADDR 290
-#define LDAP_ATTR_MASK 291
-#define LDAP_ATTR_GROUP 292
-#define LDAP_ATTR_MEMBER 293
-#define RADCFG 294
-#define RAD_AUTH 295
-#define RAD_ACCT 296
-#define RAD_TIMEOUT 297
-#define RAD_RETRIES 298
-#define MODECFG 299
-#define CFG_NET4 300
-#define CFG_MASK4 301
-#define CFG_DNS4 302
-#define CFG_NBNS4 303
-#define CFG_DEFAULT_DOMAIN 304
-#define CFG_AUTH_SOURCE 305
-#define CFG_AUTH_GROUPS 306
-#define CFG_SYSTEM 307
-#define CFG_RADIUS 308
-#define CFG_PAM 309
-#define CFG_LDAP 310
-#define CFG_LOCAL 311
-#define CFG_NONE 312
-#define CFG_GROUP_SOURCE 313
-#define CFG_ACCOUNTING 314
-#define CFG_CONF_SOURCE 315
-#define CFG_MOTD 316
-#define CFG_POOL_SIZE 317
-#define CFG_AUTH_THROTTLE 318
-#define CFG_SPLIT_NETWORK 319
-#define CFG_SPLIT_LOCAL 320
-#define CFG_SPLIT_INCLUDE 321
-#define CFG_SPLIT_DNS 322
-#define CFG_PFS_GROUP 323
-#define CFG_SAVE_PASSWD 324
-#define RETRY 325
-#define RETRY_COUNTER 326
-#define RETRY_INTERVAL 327
-#define RETRY_PERSEND 328
-#define RETRY_PHASE1 329
-#define RETRY_PHASE2 330
-#define NATT_KA 331
-#define ALGORITHM_CLASS 332
-#define ALGORITHMTYPE 333
-#define STRENGTHTYPE 334
-#define SAINFO 335
-#define FROM 336
-#define REMOTE 337
-#define ANONYMOUS 338
-#define CLIENTADDR 339
-#define INHERIT 340
-#define REMOTE_ADDRESS 341
-#define EXCHANGE_MODE 342
-#define EXCHANGETYPE 343
-#define DOI 344
-#define DOITYPE 345
-#define SITUATION 346
-#define SITUATIONTYPE 347
-#define CERTIFICATE_TYPE 348
-#define CERTTYPE 349
-#define PEERS_CERTFILE 350
-#define CA_TYPE 351
-#define VERIFY_CERT 352
-#define SEND_CERT 353
-#define SEND_CR 354
-#define MATCH_EMPTY_CR 355
-#define IDENTIFIERTYPE 356
-#define IDENTIFIERQUAL 357
-#define MY_IDENTIFIER 358
-#define PEERS_IDENTIFIER 359
-#define VERIFY_IDENTIFIER 360
-#define DNSSEC 361
-#define CERT_X509 362
-#define CERT_PLAINRSA 363
-#define NONCE_SIZE 364
-#define DH_GROUP 365
-#define KEEPALIVE 366
-#define PASSIVE 367
-#define INITIAL_CONTACT 368
-#define NAT_TRAVERSAL 369
-#define REMOTE_FORCE_LEVEL 370
-#define PROPOSAL_CHECK 371
-#define PROPOSAL_CHECK_LEVEL 372
-#define GENERATE_POLICY 373
-#define GENERATE_LEVEL 374
-#define SUPPORT_PROXY 375
-#define PROPOSAL 376
-#define EXEC_PATH 377
-#define EXEC_COMMAND 378
-#define EXEC_SUCCESS 379
-#define EXEC_FAILURE 380
-#define GSS_ID 381
-#define GSS_ID_ENC 382
-#define GSS_ID_ENCTYPE 383
-#define COMPLEX_BUNDLE 384
-#define DPD 385
-#define DPD_DELAY 386
-#define DPD_RETRY 387
-#define DPD_MAXFAIL 388
-#define PH1ID 389
-#define XAUTH_LOGIN 390
-#define WEAK_PHASE1_CHECK 391
-#define REKEY 392
-#define PREFIX 393
-#define PORT 394
-#define PORTANY 395
-#define UL_PROTO 396
-#define ANY 397
-#define IKE_FRAG 398
-#define ESP_FRAG 399
-#define MODE_CFG 400
-#define PFS_GROUP 401
-#define LIFETIME 402
-#define LIFETYPE_TIME 403
-#define LIFETYPE_BYTE 404
-#define STRENGTH 405
-#define REMOTEID 406
-#define SCRIPT 407
-#define PHASE1_UP 408
-#define PHASE1_DOWN 409
-#define PHASE1_DEAD 410
-#define NUMBER 411
-#define SWITCH 412
-#define BOOLEAN 413
-#define HEXSTRING 414
-#define QUOTEDSTRING 415
-#define ADDRSTRING 416
-#define ADDRRANGE 417
-#define UNITTYPE_BYTE 418
-#define UNITTYPE_KBYTES 419
-#define UNITTYPE_MBYTES 420
-#define UNITTYPE_TBYTES 421
-#define UNITTYPE_SEC 422
-#define UNITTYPE_MIN 423
-#define UNITTYPE_HOUR 424
-#define EOS 425
-#define BOC 426
-#define EOC 427
-#define COMMA 428
+#define IDENTIFIER 265
+#define VENDORID 266
+#define LOGGING 267
+#define LOGLEV 268
+#define PADDING 269
+#define PAD_RANDOMIZE 270
+#define PAD_RANDOMIZELEN 271
+#define PAD_MAXLEN 272
+#define PAD_STRICT 273
+#define PAD_EXCLTAIL 274
+#define LISTEN 275
+#define X_ISAKMP 276
+#define X_ISAKMP_NATT 277
+#define X_ADMIN 278
+#define STRICT_ADDRESS 279
+#define ADMINSOCK 280
+#define DISABLED 281
+#define LDAPCFG 282
+#define LDAP_HOST 283
+#define LDAP_PORT 284
+#define LDAP_PVER 285
+#define LDAP_BASE 286
+#define LDAP_BIND_DN 287
+#define LDAP_BIND_PW 288
+#define LDAP_SUBTREE 289
+#define LDAP_ATTR_USER 290
+#define LDAP_ATTR_ADDR 291
+#define LDAP_ATTR_MASK 292
+#define LDAP_ATTR_GROUP 293
+#define LDAP_ATTR_MEMBER 294
+#define MODECFG 295
+#define CFG_NET4 296
+#define CFG_MASK4 297
+#define CFG_DNS4 298
+#define CFG_NBNS4 299
+#define CFG_DEFAULT_DOMAIN 300
+#define CFG_AUTH_SOURCE 301
+#define CFG_AUTH_GROUPS 302
+#define CFG_SYSTEM 303
+#define CFG_RADIUS 304
+#define CFG_PAM 305
+#define CFG_LDAP 306
+#define CFG_LOCAL 307
+#define CFG_NONE 308
+#define CFG_GROUP_SOURCE 309
+#define CFG_ACCOUNTING 310
+#define CFG_CONF_SOURCE 311
+#define CFG_MOTD 312
+#define CFG_POOL_SIZE 313
+#define CFG_AUTH_THROTTLE 314
+#define CFG_SPLIT_NETWORK 315
+#define CFG_SPLIT_LOCAL 316
+#define CFG_SPLIT_INCLUDE 317
+#define CFG_SPLIT_DNS 318
+#define CFG_PFS_GROUP 319
+#define CFG_SAVE_PASSWD 320
+#define RETRY 321
+#define RETRY_COUNTER 322
+#define RETRY_INTERVAL 323
+#define RETRY_PERSEND 324
+#define RETRY_PHASE1 325
+#define RETRY_PHASE2 326
+#define NATT_KA 327
+#define ALGORITHM_CLASS 328
+#define ALGORITHMTYPE 329
+#define STRENGTHTYPE 330
+#define SAINFO 331
+#define FROM 332
+#define REMOTE 333
+#define ANONYMOUS 334
+#define INHERIT 335
+#define EXCHANGE_MODE 336
+#define EXCHANGETYPE 337
+#define DOI 338
+#define DOITYPE 339
+#define SITUATION 340
+#define SITUATIONTYPE 341
+#define CERTIFICATE_TYPE 342
+#define CERTTYPE 343
+#define PEERS_CERTFILE 344
+#define CA_TYPE 345
+#define VERIFY_CERT 346
+#define SEND_CERT 347
+#define SEND_CR 348
+#define IDENTIFIERTYPE 349
+#define IDENTIFIERQUAL 350
+#define MY_IDENTIFIER 351
+#define PEERS_IDENTIFIER 352
+#define VERIFY_IDENTIFIER 353
+#define DNSSEC 354
+#define CERT_X509 355
+#define CERT_PLAINRSA 356
+#define NONCE_SIZE 357
+#define DH_GROUP 358
+#define KEEPALIVE 359
+#define PASSIVE 360
+#define INITIAL_CONTACT 361
+#define NAT_TRAVERSAL 362
+#define REMOTE_FORCE_LEVEL 363
+#define PROPOSAL_CHECK 364
+#define PROPOSAL_CHECK_LEVEL 365
+#define GENERATE_POLICY 366
+#define GENERATE_LEVEL 367
+#define SUPPORT_PROXY 368
+#define PROPOSAL 369
+#define EXEC_PATH 370
+#define EXEC_COMMAND 371
+#define EXEC_SUCCESS 372
+#define EXEC_FAILURE 373
+#define GSS_ID 374
+#define GSS_ID_ENC 375
+#define GSS_ID_ENCTYPE 376
+#define COMPLEX_BUNDLE 377
+#define DPD 378
+#define DPD_DELAY 379
+#define DPD_RETRY 380
+#define DPD_MAXFAIL 381
+#define PH1ID 382
+#define XAUTH_LOGIN 383
+#define WEAK_PHASE1_CHECK 384
+#define PREFIX 385
+#define PORT 386
+#define PORTANY 387
+#define UL_PROTO 388
+#define ANY 389
+#define IKE_FRAG 390
+#define ESP_FRAG 391
+#define MODE_CFG 392
+#define PFS_GROUP 393
+#define LIFETIME 394
+#define LIFETYPE_TIME 395
+#define LIFETYPE_BYTE 396
+#define STRENGTH 397
+#define REMOTEID 398
+#define SCRIPT 399
+#define PHASE1_UP 400
+#define PHASE1_DOWN 401
+#define NUMBER 402
+#define SWITCH 403
+#define BOOLEAN 404
+#define HEXSTRING 405
+#define QUOTEDSTRING 406
+#define ADDRSTRING 407
+#define ADDRRANGE 408
+#define UNITTYPE_BYTE 409
+#define UNITTYPE_KBYTES 410
+#define UNITTYPE_MBYTES 411
+#define UNITTYPE_TBYTES 412
+#define UNITTYPE_SEC 413
+#define UNITTYPE_MIN 414
+#define UNITTYPE_HOUR 415
+#define EOS 416
+#define BOC 417
+#define EOC 418
+#define COMMA 419
 
 
 
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
+#line 174 "cfparse.y"
 {
-
-/* Line 1676 of yacc.c  */
-#line 177 "cfparse.y"
-
 	unsigned long num;
 	vchar_t *val;
 	struct remoteconf *rmconf;
 	struct sockaddr *saddr;
 	struct sainfoalg *alg;
-
-
-
-/* Line 1676 of yacc.c  */
-#line 408 "cfparse.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1489 of yacc.c.  */
+#line 385 "cfparse.h"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE yylval;
 
-
diff --git a/src/racoon/cfparse.y b/src/racoon/cfparse.y
index 12920d8..540c400 100644
--- a/src/racoon/cfparse.y
+++ b/src/racoon/cfparse.y
@@ -1,4 +1,4 @@
-/*	$NetBSD: cfparse.y,v 1.42 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: cfparse.y,v 1.18.4.7 2008/07/21 20:45:32 tteras Exp $	*/
 
 /* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */
 
@@ -94,7 +94,14 @@
 #endif
 #include "vendorid.h"
 #include "rsalist.h"
-#include "crypto_openssl.h"
+
+struct proposalspec {
+	time_t lifetime;		/* for isakmp/ipsec */
+	int lifebyte;			/* for isakmp/ipsec */
+	struct secprotospec *spspec;	/* the head is always current spec. */
+	struct proposalspec *next;	/* the tail is the most prefered. */
+	struct proposalspec *prev;
+};
 
 struct secprotospec {
 	int prop_no;
@@ -113,6 +120,7 @@
 
 	struct secprotospec *next;	/* the tail is the most prefiered. */
 	struct secprotospec *prev;
+	struct proposalspec *back;
 };
 
 static int num2dhgroup[] = {
@@ -143,35 +151,24 @@
 static int cur_algclass;
 static int oldloglevel = LLV_BASE;
 
+static struct proposalspec *newprspec __P((void));
+static void insprspec __P((struct proposalspec *, struct proposalspec **));
 static struct secprotospec *newspspec __P((void));
-static void insspspec __P((struct remoteconf *, struct secprotospec *));
-void dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src));
-void flushspspec __P((struct remoteconf *));
+static void insspspec __P((struct secprotospec *, struct proposalspec **));
 static void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int));
 
-static int set_isakmp_proposal __P((struct remoteconf *));
+static int set_isakmp_proposal
+	__P((struct remoteconf *, struct proposalspec *));
 static void clean_tmpalgtype __P((void));
 static int expand_isakmpspec __P((int, int, int *,
 	int, int, time_t, int, int, int, char *, struct remoteconf *));
+static int listen_addr __P((struct sockaddr *addr, int udp_encap));
 
 void freeetypes (struct etypes **etypes);
 
-static int load_x509(const char *file, char **filenameptr,
-		     vchar_t **certptr)
-{
-	char path[PATH_MAX];
-
-	getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file);
-	*certptr = eay_get_x509cert(path);
-	if (*certptr == NULL)
-		return -1;
-
-	*filenameptr = racoon_strdup(file);
-	STRDUP_FATAL(*filenameptr);
-
-	return 0;
-}
-
+#if 0
+static int fix_lifebyte __P((u_long));
+#endif
 %}
 
 %union {
@@ -188,8 +185,8 @@
 %token PATH PATHTYPE
 	/* include */
 %token INCLUDE
-	/* PFKEY_BUFFER */
-%token PFKEY_BUFFER
+	/* self information */
+%token IDENTIFIER VENDORID
 	/* logging */
 %token LOGGING LOGLEV
 	/* padding */
@@ -199,8 +196,6 @@
 	/* ldap config */
 %token LDAPCFG LDAP_HOST LDAP_PORT LDAP_PVER LDAP_BASE LDAP_BIND_DN LDAP_BIND_PW LDAP_SUBTREE
 %token LDAP_ATTR_USER LDAP_ATTR_ADDR LDAP_ATTR_MASK LDAP_ATTR_GROUP LDAP_ATTR_MEMBER
-	/* radius config */
-%token RADCFG RAD_AUTH RAD_ACCT RAD_TIMEOUT RAD_RETRIES
 	/* modecfg */
 %token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN
 %token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE
@@ -216,10 +211,10 @@
 	/* sainfo */
 %token SAINFO FROM
 	/* remote */
-%token REMOTE ANONYMOUS CLIENTADDR INHERIT REMOTE_ADDRESS
+%token REMOTE ANONYMOUS INHERIT
 %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE
 %token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE
-%token VERIFY_CERT SEND_CERT SEND_CR MATCH_EMPTY_CR
+%token VERIFY_CERT SEND_CERT SEND_CR
 %token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER 
 %token PEERS_IDENTIFIER VERIFY_IDENTIFIER
 %token DNSSEC CERT_X509 CERT_PLAINRSA
@@ -234,12 +229,11 @@
 %token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL
 %token PH1ID
 %token XAUTH_LOGIN WEAK_PHASE1_CHECK
-%token REKEY
 
 %token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG
 %token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID
 
-%token SCRIPT PHASE1_UP PHASE1_DOWN PHASE1_DEAD
+%token SCRIPT PHASE1_UP PHASE1_DOWN
 
 %token NUMBER SWITCH BOOLEAN
 %token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE
@@ -271,13 +265,12 @@
 	:	privsep_statement
 	|	path_statement
 	|	include_statement
-	|	pfkey_statement
 	|	gssenc_statement
+	|	identifier_statement
 	|	logging_statement
 	|	padding_statement
 	|	listen_statement
 	|	ldapcfg_statement
-	|	radcfg_statement
 	|	modecfg_statement
 	|	timer_statement
 	|	sainfo_statement
@@ -361,13 +354,6 @@
 		}
 	;
 
-    /* pfkey_buffer */
-pfkey_statement
-    :   PFKEY_BUFFER NUMBER EOS
-        {
-			lcconf->pfkey_buffer_size = $2;
-        }
-    ;
 	/* gss_id_enc */
 gssenc_statement
 	:	GSS_ID_ENC GSS_ID_ENCTYPE EOS
@@ -380,12 +366,45 @@
 		}
 	;
 
+	/* self information */
+identifier_statement
+	:	IDENTIFIER identifier_stmt
+	;
+identifier_stmt
+	:	VENDORID
+		{
+			/*XXX to be deleted */
+		}
+		QUOTEDSTRING EOS
+	|	IDENTIFIERTYPE QUOTEDSTRING
+		{
+			/*XXX to be deleted */
+			$2->l--;	/* nuke '\0' */
+			lcconf->ident[$1] = $2;
+			if (lcconf->ident[$1] == NULL) {
+				yyerror("failed to set my ident: %s",
+					strerror(errno));
+				return -1;
+			}
+		}
+		EOS
+	;
+
 	/* logging */
 logging_statement
 	:	LOGGING log_level EOS
 	;
 log_level
-	:	LOGLEV
+	:	HEXSTRING
+		{
+			/*
+			 * XXX ignore it because this specification
+			 * will be obsoleted.
+			 */
+			yywarn("see racoon.conf(5), such a log specification will be obsoleted.");
+			vfree($1);
+		}
+	|	LOGLEV
 		{
 			/*
 			 * set the loglevel to the value specified
@@ -424,21 +443,23 @@
 listen_stmt
 	:	X_ISAKMP ike_addrinfo_port
 		{
-			myaddr_listen($2, FALSE);
-			racoon_free($2);
+			listen_addr ($2, 0);
 		}
 		EOS
 	|	X_ISAKMP_NATT ike_addrinfo_port
 		{
 #ifdef ENABLE_NATT
-			myaddr_listen($2, TRUE);
-			racoon_free($2);
+			listen_addr ($2, 1);
 #else
-			racoon_free($2);
 			yyerror("NAT-T support not compiled in.");
 #endif
 		}
 		EOS
+	|	X_ADMIN
+		{
+			yyerror("admin directive is obsoleted.");
+		}
+		PORT EOS
 	|	ADMINSOCK QUOTEDSTRING QUOTEDSTRING QUOTEDSTRING NUMBER 
 		{
 #ifdef ENABLE_ADMINPORT
@@ -485,122 +506,6 @@
 	|	PORT		{ $$ = $1; }
 	;
 
-	/* radius configuration */
-radcfg_statement
-	:	RADCFG {
-#ifndef ENABLE_HYBRID
-			yyerror("racoon not configured with --enable-hybrid");
-			return -1;
-#endif
-#ifndef HAVE_LIBRADIUS
-			yyerror("racoon not configured with --with-libradius");
-			return -1;
-#endif
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			xauth_rad_config.timeout = 3;
-			xauth_rad_config.retries = 3;
-#endif
-#endif
-		} BOC radcfg_stmts EOC
-	;
-radcfg_stmts
-	:	/* nothing */
-	|	radcfg_stmts radcfg_stmt
-	;
-radcfg_stmt
-	:	RAD_AUTH QUOTEDSTRING QUOTEDSTRING
-		{
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			int i = xauth_rad_config.auth_server_count;
-			if (i == RADIUS_MAX_SERVERS) {
-				yyerror("maximum radius auth servers exceeded");
-				return -1;
-			}
-
-			xauth_rad_config.auth_server_list[i].host = vdup($2);
-			xauth_rad_config.auth_server_list[i].secret = vdup($3);
-			xauth_rad_config.auth_server_list[i].port = 0; // default port
-			xauth_rad_config.auth_server_count++;
-#endif
-#endif
-		}
-		EOS
-	|	RAD_AUTH QUOTEDSTRING NUMBER QUOTEDSTRING
-		{
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			int i = xauth_rad_config.auth_server_count;
-			if (i == RADIUS_MAX_SERVERS) {
-				yyerror("maximum radius auth servers exceeded");
-				return -1;
-			}
-
-			xauth_rad_config.auth_server_list[i].host = vdup($2);
-			xauth_rad_config.auth_server_list[i].secret = vdup($4);
-			xauth_rad_config.auth_server_list[i].port = $3;
-			xauth_rad_config.auth_server_count++;
-#endif
-#endif
-		}
-		EOS
-	|	RAD_ACCT QUOTEDSTRING QUOTEDSTRING
-		{
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			int i = xauth_rad_config.acct_server_count;
-			if (i == RADIUS_MAX_SERVERS) {
-				yyerror("maximum radius account servers exceeded");
-				return -1;
-			}
-
-			xauth_rad_config.acct_server_list[i].host = vdup($2);
-			xauth_rad_config.acct_server_list[i].secret = vdup($3);
-			xauth_rad_config.acct_server_list[i].port = 0; // default port
-			xauth_rad_config.acct_server_count++;
-#endif
-#endif
-		}
-		EOS
-	|	RAD_ACCT QUOTEDSTRING NUMBER QUOTEDSTRING
-		{
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			int i = xauth_rad_config.acct_server_count;
-			if (i == RADIUS_MAX_SERVERS) {
-				yyerror("maximum radius account servers exceeded");
-				return -1;
-			}
-
-			xauth_rad_config.acct_server_list[i].host = vdup($2);
-			xauth_rad_config.acct_server_list[i].secret = vdup($4);
-			xauth_rad_config.acct_server_list[i].port = $3;
-			xauth_rad_config.acct_server_count++;
-#endif
-#endif
-		}
-		EOS
-	|	RAD_TIMEOUT NUMBER
-		{
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			xauth_rad_config.timeout = $2;
-#endif
-#endif
-		}
-		EOS
-	|	RAD_RETRIES NUMBER
-		{
-#ifdef ENABLE_HYBRID
-#ifdef HAVE_LIBRADIUS
-			xauth_rad_config.retries = $2;
-#endif
-#endif
-		}
-		EOS
-	;
-
 	/* ldap configuration */
 ldapcfg_statement
 	:	LDAPCFG {
@@ -1110,16 +1015,12 @@
 
 			grouplist = racoon_realloc(icc->grouplist,
 					sizeof(char**)*(icc->groupcount+1));
-			if (grouplist == NULL) {
+			if (grouplist == NULL)
 				yyerror("unable to allocate auth group list");
-				return -1;
-			}
 
 			groupname = racoon_malloc($1->l+1);
-			if (groupname == NULL) {
+			if (groupname == NULL)
 				yyerror("unable to allocate auth group name");
-				return -1;
-			}
 
 			memcpy(groupname,$1->v,$1->l);
 			groupname[$1->l]=0;
@@ -1147,10 +1048,8 @@
 			if (!icc->splitdns_len)
 			{
 				icc->splitdns_list = racoon_malloc($1->l);
-				if(icc->splitdns_list == NULL) {
+				if(icc->splitdns_list == NULL)
 					yyerror("error allocating splitdns list buffer");
-					return -1;
-				}
 				memcpy(icc->splitdns_list,$1->v,$1->l);
 				icc->splitdns_len = $1->l;
 			}
@@ -1158,10 +1057,8 @@
 			{
 				int len = icc->splitdns_len + $1->l + 1;
 				icc->splitdns_list = racoon_realloc(icc->splitdns_list,len);
-				if(icc->splitdns_list == NULL) {
+				if(icc->splitdns_list == NULL)
 					yyerror("error allocating splitdns list buffer");
-					return -1;
-				}
 				icc->splitdns_list[icc->splitdns_len] = ',';
 				memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l);
 				icc->splitdns_len = len;
@@ -1257,16 +1154,12 @@
 			check = getsainfo(cur_sainfo->idsrc,
 					  cur_sainfo->iddst,
 					  cur_sainfo->id_i,
-					  NULL,
 					  cur_sainfo->remoteid);
-
-			if (check && ((check->idsrc != SAINFO_ANONYMOUS) &&
-				      (cur_sainfo->idsrc != SAINFO_ANONYMOUS))) {
+			if (check && (!check->idsrc && !cur_sainfo->idsrc)) {
 				yyerror("duplicated sainfo: %s",
 					sainfo2str(cur_sainfo));
 				return -1;
 			}
-
 			inssainfo(cur_sainfo);
 		}
 		EOC
@@ -1274,28 +1167,18 @@
 sainfo_name
 	:	ANONYMOUS
 		{
-			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
-			cur_sainfo->iddst = SAINFO_ANONYMOUS;
-		}
-	|	ANONYMOUS CLIENTADDR
-		{
-			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
-			cur_sainfo->iddst = SAINFO_CLIENTADDR;
+			cur_sainfo->idsrc = NULL;
+			cur_sainfo->iddst = NULL;
 		}
 	|	ANONYMOUS sainfo_id
 		{
-			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
+			cur_sainfo->idsrc = NULL;
 			cur_sainfo->iddst = $2;
 		}
 	|	sainfo_id ANONYMOUS
 		{
 			cur_sainfo->idsrc = $1;
-			cur_sainfo->iddst = SAINFO_ANONYMOUS;
-		}
-	|	sainfo_id CLIENTADDR
-		{
-			cur_sainfo->idsrc = $1;
-			cur_sainfo->iddst = SAINFO_CLIENTADDR;
+			cur_sainfo->iddst = NULL;
 		}
 	|	sainfo_id sainfo_id
 		{
@@ -1524,6 +1407,16 @@
 			cur_algclass = $1;
 		}
 		algorithms EOS
+	|	IDENTIFIER IDENTIFIERTYPE
+		{
+			yyerror("it's deprecated to specify a identifier in phase 2");
+		}
+		EOS
+	|	MY_IDENTIFIER IDENTIFIERTYPE QUOTEDSTRING
+		{
+			yyerror("it's deprecated to specify a identifier in phase 2");
+		}
+		EOS
 	;
 
 algorithms
@@ -1614,82 +1507,36 @@
 
 	/* remote */
 remote_statement
-	: REMOTE QUOTEDSTRING INHERIT QUOTEDSTRING
-		{
-			struct remoteconf *from, *new;
-
-			if (getrmconf_by_name($2->v) != NULL) {
-				yyerror("named remoteconf \"%s\" already exists.");
-				return -1;
-			}
-
-			from = getrmconf_by_name($4->v);
-			if (from == NULL) {
-				yyerror("named parent remoteconf \"%s\" does not exist.",
-					$4->v);
-				return -1;
-			}
-
-			new = duprmconf_shallow(from);
-			if (new == NULL) {
-				yyerror("failed to duplicate remoteconf from \"%s\".",
-					$4->v);
-				return -1;
-			}
-
-			new->name = racoon_strdup($2->v);
-			cur_rmconf = new;
-
-			vfree($2);
-			vfree($4);
-		}
-		remote_specs_block
-	| REMOTE QUOTEDSTRING
+	:	REMOTE remote_index INHERIT remote_index
 		{
 			struct remoteconf *new;
+			struct proposalspec *prspec;
 
-			if (getrmconf_by_name($2->v) != NULL) {
-				yyerror("Named remoteconf \"%s\" already exists.");
-				return -1;
-			}
-
-			new = newrmconf();
+			new = copyrmconf($4);
 			if (new == NULL) {
-				yyerror("failed to get new remoteconf.");
-				return -1;
-			}
-			new->name = racoon_strdup($2->v);
-			cur_rmconf = new;
-
-			vfree($2);
-		}
-		remote_specs_block
-	| REMOTE remote_index INHERIT remote_index
-		{
-			struct remoteconf *from, *new;
-
-			from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS);
-			if (from == NULL) {
-				yyerror("failed to get remoteconf for %s.",
-					saddr2str($4));
+				yyerror("failed to get remoteconf for %s.", saddr2str ($4));
 				return -1;
 			}
 
-			new = duprmconf_shallow(from);
-			if (new == NULL) {
-				yyerror("failed to duplicate remoteconf from %s.",
-					saddr2str($4));
-				return -1;
-			}
-
-			racoon_free($4);
 			new->remote = $2;
+			new->inherited_from = getrmconf_strict($4, 1);
+			new->proposal = NULL;
+			new->prhead = NULL;
 			cur_rmconf = new;
+
+			prspec = newprspec();
+			if (prspec == NULL || !cur_rmconf->inherited_from 
+				|| !cur_rmconf->inherited_from->proposal)
+				return -1;
+			prspec->lifetime = cur_rmconf->inherited_from->proposal->lifetime;
+			prspec->lifebyte = cur_rmconf->inherited_from->proposal->lifebyte;
+			insprspec(prspec, &cur_rmconf->prhead);
 		}
 		remote_specs_block
 	|	REMOTE remote_index
 		{
 			struct remoteconf *new;
+			struct proposalspec *prspec;
 
 			new = newrmconf();
 			if (new == NULL) {
@@ -1699,6 +1546,12 @@
 
 			new->remote = $2;
 			cur_rmconf = new;
+
+			prspec = newprspec();
+			if (prspec == NULL)
+				return -1;
+			prspec->lifetime = oakley_get_defaultlifetime();
+			insprspec(prspec, &cur_rmconf->prhead);
 		}
 		remote_specs_block
 	;
@@ -1715,6 +1568,7 @@
 			if (cur_rmconf->idvtype == IDTYPE_UNDEFINED)
 				cur_rmconf->idvtype = IDTYPE_ADDRESS;
 
+
 			if (cur_rmconf->idvtype == IDTYPE_ASN1DN) {
 				if (cur_rmconf->mycertfile) {
 					if (cur_rmconf->idv)
@@ -1729,24 +1583,17 @@
 					return -1;
 				}
 			}
-
-			if (duprmconf_finish(cur_rmconf))
-				return -1;
-
-#if 0
-			/* this pointer copy will never happen, because duprmconf_shallow
-			 * already copied all pointers.
-			 */
-			if (cur_rmconf->spspec == NULL &&
-			    cur_rmconf->inherited_from != NULL) {
-				cur_rmconf->spspec = cur_rmconf->inherited_from->spspec;
+			
+			if (cur_rmconf->prhead->spspec == NULL
+				&& cur_rmconf->inherited_from
+				&& cur_rmconf->inherited_from->prhead) {
+				cur_rmconf->prhead->spspec = cur_rmconf->inherited_from->prhead->spspec;
 			}
-#endif
-			if (set_isakmp_proposal(cur_rmconf) != 0)
+			if (set_isakmp_proposal(cur_rmconf, cur_rmconf->prhead) != 0)
 				return -1;
 
 			/* DH group settting if aggressive mode is there. */
-			if (check_etypeok(cur_rmconf, (void*) ISAKMP_ETYPE_AGG)) {
+			if (check_etypeok(cur_rmconf, ISAKMP_ETYPE_AGG) != NULL) {
 				struct isakmpsa *p;
 				int b = 0;
 
@@ -1801,16 +1648,7 @@
 	|	remote_specs remote_spec
 	;
 remote_spec
-	:	REMOTE_ADDRESS ike_addrinfo_port
-		{
-			if (cur_rmconf->remote != NULL) {
-				yyerror("remote_address already specified");
-				return -1;
-			}
-			cur_rmconf->remote = $2;
-		}
-		EOS
-	|	EXCHANGE_MODE
+	:	EXCHANGE_MODE
 		{
 			cur_rmconf->etypes = NULL;
 		}
@@ -1822,36 +1660,33 @@
 		{
 			yywarn("This directive without certtype will be removed!\n");
 			yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v);
+			cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
 
-			if (cur_rmconf->peerscert != NULL) {
-				yyerror("peers_certfile already defined\n");
-				return -1;
-			}
-
-			if (load_x509($2->v, &cur_rmconf->peerscertfile,
-				      &cur_rmconf->peerscert)) {
-				yyerror("failed to load certificate \"%s\"\n",
-					$2->v);
-				return -1;
-			}
-
+			if (cur_rmconf->peerscertfile != NULL)
+				racoon_free(cur_rmconf->peerscertfile);
+			cur_rmconf->peerscertfile = racoon_strdup($2->v);
+			STRDUP_FATAL(cur_rmconf->peerscertfile);
 			vfree($2);
 		}
 		EOS
+	|	CA_TYPE CERT_X509 QUOTEDSTRING
+		{
+			cur_rmconf->cacerttype = $2;
+			cur_rmconf->getcacert_method = ISAKMP_GETCERT_LOCALFILE;
+			if (cur_rmconf->cacertfile != NULL)
+				racoon_free(cur_rmconf->cacertfile);
+			cur_rmconf->cacertfile = racoon_strdup($3->v);
+			STRDUP_FATAL(cur_rmconf->cacertfile);
+			vfree($3);
+		}
+		EOS
 	|	PEERS_CERTFILE CERT_X509 QUOTEDSTRING
 		{
-			if (cur_rmconf->peerscert != NULL) {
-				yyerror("peers_certfile already defined\n");
-				return -1;
-			}
-
-			if (load_x509($3->v, &cur_rmconf->peerscertfile,
-				      &cur_rmconf->peerscert)) {
-				yyerror("failed to load certificate \"%s\"\n",
-					$3->v);
-				return -1;
-			}
-
+			cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
+			if (cur_rmconf->peerscertfile != NULL)
+				racoon_free(cur_rmconf->peerscertfile);
+			cur_rmconf->peerscertfile = racoon_strdup($3->v);
+			STRDUP_FATAL(cur_rmconf->peerscertfile);
 			vfree($3);
 		}
 		EOS
@@ -1860,66 +1695,37 @@
 			char path[MAXPATHLEN];
 			int ret = 0;
 
-			if (cur_rmconf->peerscert != NULL) {
-				yyerror("peers_certfile already defined\n");
-				return -1;
-			}
-
-			cur_rmconf->peerscert = vmalloc(1);
-			if (cur_rmconf->peerscert == NULL) {
-				yyerror("failed to allocate peerscert");
-				return -1;
-			}
-			cur_rmconf->peerscert->v[0] = ISAKMP_CERT_PLAINRSA;
-
 			getpathname(path, sizeof(path),
-				    LC_PATHTYPE_CERT, $3->v);
-			if (rsa_parse_file(cur_rmconf->rsa_public, path,
-					   RSA_TYPE_PUBLIC)) {
+				LC_PATHTYPE_CERT, $3->v);
+			vfree($3);
+
+			if (cur_rmconf->getcert_method == ISAKMP_GETCERT_DNS) {
+				yyerror("Different peers_certfile method "
+					"already defined: %d!\n",
+					cur_rmconf->getcert_method);
+				return -1;
+			}
+			cur_rmconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
+			if (rsa_parse_file(cur_rmconf->rsa_public, path, RSA_TYPE_PUBLIC)) {
 				yyerror("Couldn't parse keyfile.\n", path);
 				return -1;
 			}
-			plog(LLV_DEBUG, LOCATION, NULL,
-			     "Public PlainRSA keyfile parsed: %s\n", path);
-
-			vfree($3);
+			plog(LLV_DEBUG, LOCATION, NULL, "Public PlainRSA keyfile parsed: %s\n", path);
 		}
 		EOS
 	|	PEERS_CERTFILE DNSSEC
 		{
-			if (cur_rmconf->peerscert != NULL) {
-				yyerror("peers_certfile already defined\n");
+			if (cur_rmconf->getcert_method) {
+				yyerror("Different peers_certfile method already defined!\n");
 				return -1;
 			}
-			cur_rmconf->peerscert = vmalloc(1);
-			if (cur_rmconf->peerscert == NULL) {
-				yyerror("failed to allocate peerscert");
-				return -1;
-			}
-			cur_rmconf->peerscert->v[0] = ISAKMP_CERT_DNS;
-		}
-		EOS
-	|	CA_TYPE CERT_X509 QUOTEDSTRING
-		{
-			if (cur_rmconf->cacert != NULL) {
-				yyerror("ca_type already defined\n");
-				return -1;
-			}
-
-			if (load_x509($3->v, &cur_rmconf->cacertfile,
-				      &cur_rmconf->cacert)) {
-				yyerror("failed to load certificate \"%s\"\n",
-					$3->v);
-				return -1;
-			}
-
-			vfree($3);
+			cur_rmconf->getcert_method = ISAKMP_GETCERT_DNS;
+			cur_rmconf->peerscertfile = NULL;
 		}
 		EOS
 	|	VERIFY_CERT SWITCH { cur_rmconf->verify_cert = $2; } EOS
 	|	SEND_CERT SWITCH { cur_rmconf->send_cert = $2; } EOS
 	|	SEND_CR SWITCH { cur_rmconf->send_cr = $2; } EOS
-	|	MATCH_EMPTY_CR SWITCH { cur_rmconf->match_empty_cr = $2; } EOS
 	|	MY_IDENTIFIER IDENTIFIERTYPE identifierstring
 		{
 			if (set_identifier(&cur_rmconf->idv, $2, $3) != 0) {
@@ -2024,13 +1830,6 @@
 			cur_rmconf->script[SCRIPT_PHASE1_DOWN] = 
 			    script_path_add(vdup($2));
 		} EOS
-	|	SCRIPT QUOTEDSTRING PHASE1_DEAD { 
-			if (cur_rmconf->script[SCRIPT_PHASE1_DEAD] != NULL)
-				vfree(cur_rmconf->script[SCRIPT_PHASE1_DEAD]);
-
-			cur_rmconf->script[SCRIPT_PHASE1_DEAD] = 
-			    script_path_add(vdup($2));
-		} EOS
 	|	MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS
 	|	WEAK_PHASE1_CHECK SWITCH {
 			cur_rmconf->weak_phase1_check = $2;
@@ -2096,8 +1895,6 @@
 #endif
 		}
 		EOS
-	|	REKEY SWITCH { cur_rmconf->rekey = $2; } EOS
-	|	REKEY REMOTE_FORCE_LEVEL { cur_rmconf->rekey = REKEY_FORCE; } EOS
 	|	PH1ID NUMBER
 		{
 			cur_rmconf->ph1id = $2;
@@ -2105,7 +1902,7 @@
 		EOS
 	|	LIFETIME LIFETYPE_TIME NUMBER unittype_time
 		{
-			cur_rmconf->lifetime = $3 * $4;
+			cur_rmconf->prhead->lifetime = $3 * $4;
 		}
 		EOS
 	|	PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL { cur_rmconf->pcheck_level = $2; } EOS
@@ -2117,8 +1914,8 @@
 #else
 			yywarn("the lifetime of bytes in phase 1 "
 				"will be ignored at the moment.");
-			cur_rmconf->lifebyte = fix_lifebyte($3 * $4);
-			if (cur_rmconf->lifebyte == 0)
+			cur_rmconf->prhead->lifebyte = fix_lifebyte($3 * $4);
+			if (cur_rmconf->prhead->lifebyte == 0)
 				return -1;
 #endif
 		}
@@ -2130,7 +1927,7 @@
 			spspec = newspspec();
 			if (spspec == NULL)
 				return -1;
-			insspspec(cur_rmconf, spspec);
+			insspspec(spspec, &cur_rmconf->prhead);
 		}
 		BOC isakmpproposal_specs EOC
 	;
@@ -2161,22 +1958,16 @@
 cert_spec
 	:	CERT_X509 QUOTEDSTRING QUOTEDSTRING
 		{
-			if (cur_rmconf->mycert != NULL) {
-				yyerror("certificate_type already defined\n");
-				return -1;
-			}
-
-			if (load_x509($2->v, &cur_rmconf->mycertfile,
-				      &cur_rmconf->mycert)) {
-				yyerror("failed to load certificate \"%s\"\n",
-					$2->v);
-				return -1;
-			}
-
+			cur_rmconf->certtype = $1;
+			if (cur_rmconf->mycertfile != NULL)
+				racoon_free(cur_rmconf->mycertfile);
+			cur_rmconf->mycertfile = racoon_strdup($2->v);
+			STRDUP_FATAL(cur_rmconf->mycertfile);
+			vfree($2);
+			if (cur_rmconf->myprivfile != NULL)
+				racoon_free(cur_rmconf->myprivfile);
 			cur_rmconf->myprivfile = racoon_strdup($3->v);
 			STRDUP_FATAL(cur_rmconf->myprivfile);
-
-			vfree($2);
 			vfree($3);
 		}
 		EOS
@@ -2185,31 +1976,19 @@
 			char path[MAXPATHLEN];
 			int ret = 0;
 
-			if (cur_rmconf->mycert != NULL) {
-				yyerror("certificate_type already defined\n");
-				return -1;
-			}
-
-			cur_rmconf->mycert = vmalloc(1);
-			if (cur_rmconf->mycert == NULL) {
-				yyerror("failed to allocate mycert");
-				return -1;
-			}
-			cur_rmconf->mycert->v[0] = ISAKMP_CERT_PLAINRSA;
-
 			getpathname(path, sizeof(path),
-				    LC_PATHTYPE_CERT, $2->v);
+				LC_PATHTYPE_CERT, $2->v);
+			vfree($2);
+
+			cur_rmconf->certtype = $1;
 			cur_rmconf->send_cr = FALSE;
 			cur_rmconf->send_cert = FALSE;
 			cur_rmconf->verify_cert = FALSE;
-			if (rsa_parse_file(cur_rmconf->rsa_private, path,
-					   RSA_TYPE_PRIVATE)) {
+			if (rsa_parse_file(cur_rmconf->rsa_private, path, RSA_TYPE_PRIVATE)) {
 				yyerror("Couldn't parse keyfile.\n", path);
 				return -1;
 			}
-			plog(LLV_DEBUG, LOCATION, NULL,
-			     "Private PlainRSA keyfile parsed: %s\n", path);
-			vfree($2);
+			plog(LLV_DEBUG, LOCATION, NULL, "Private PlainRSA keyfile parsed: %s\n", path);
 		}
 		EOS
 	;
@@ -2243,9 +2022,13 @@
 	|	isakmpproposal_specs isakmpproposal_spec
 	;
 isakmpproposal_spec
-	:	LIFETIME LIFETYPE_TIME NUMBER unittype_time
+	:	STRENGTH
 		{
-			cur_rmconf->spspec->lifetime = $3 * $4;
+			yyerror("strength directive is obsoleted.");
+		} STRENGTHTYPE EOS
+	|	LIFETIME LIFETYPE_TIME NUMBER unittype_time
+		{
+			cur_rmconf->prhead->spspec->lifetime = $3 * $4;
 		}
 		EOS
 	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
@@ -2254,28 +2037,28 @@
 			yyerror("byte lifetime support is deprecated");
 			return -1;
 #else
-			cur_rmconf->spspec->lifebyte = fix_lifebyte($3 * $4);
-			if (cur_rmconf->spspec->lifebyte == 0)
+			cur_rmconf->prhead->spspec->lifebyte = fix_lifebyte($3 * $4);
+			if (cur_rmconf->prhead->spspec->lifebyte == 0)
 				return -1;
 #endif
 		}
 		EOS
 	|	DH_GROUP dh_group_num
 		{
-			cur_rmconf->spspec->algclass[algclass_isakmp_dh] = $2;
+			cur_rmconf->prhead->spspec->algclass[algclass_isakmp_dh] = $2;
 		}
 		EOS
 	|	GSS_ID QUOTEDSTRING
 		{
-			if (cur_rmconf->spspec->vendorid != VENDORID_GSSAPI) {
+			if (cur_rmconf->prhead->spspec->vendorid != VENDORID_GSSAPI) {
 				yyerror("wrong Vendor ID for gssapi_id");
 				return -1;
 			}
-			if (cur_rmconf->spspec->gssid != NULL)
-				racoon_free(cur_rmconf->spspec->gssid);
-			cur_rmconf->spspec->gssid =
+			if (cur_rmconf->prhead->spspec->gssid != NULL)
+				racoon_free(cur_rmconf->prhead->spspec->gssid);
+			cur_rmconf->prhead->spspec->gssid = 
 			    racoon_strdup($2->v);
-			STRDUP_FATAL(cur_rmconf->spspec->gssid);
+			STRDUP_FATAL(cur_rmconf->prhead->spspec->gssid);
 		}
 		EOS
 	|	ALGORITHM_CLASS ALGORITHMTYPE keylength
@@ -2307,7 +2090,7 @@
 				}
 #endif
 
-				cur_rmconf->spspec->algclass[algclass_isakmp_enc] = doi;
+				cur_rmconf->prhead->spspec->algclass[algclass_isakmp_enc] = doi;
 				defklen = default_keylen($1, $2);
 				if (defklen == 0) {
 					if ($3) {
@@ -2321,22 +2104,22 @@
 					}
 				}
 				if ($3)
-					cur_rmconf->spspec->encklen = $3;
+					cur_rmconf->prhead->spspec->encklen = $3;
 				else
-					cur_rmconf->spspec->encklen = defklen;
+					cur_rmconf->prhead->spspec->encklen = defklen;
 				break;
 			case algclass_isakmp_hash:
-				cur_rmconf->spspec->algclass[algclass_isakmp_hash] = doi;
+				cur_rmconf->prhead->spspec->algclass[algclass_isakmp_hash] = doi;
 				break;
 			case algclass_isakmp_ameth:
-				cur_rmconf->spspec->algclass[algclass_isakmp_ameth] = doi;
+				cur_rmconf->prhead->spspec->algclass[algclass_isakmp_ameth] = doi;
 				/*
 				 * We may have to set the Vendor ID for the
 				 * authentication method we're using.
 				 */
 				switch ($2) {
 				case algtype_gssapikrb:
-					if (cur_rmconf->spspec->vendorid !=
+					if (cur_rmconf->prhead->spspec->vendorid !=
 					    VENDORID_UNKNOWN) {
 						yyerror("Vendor ID mismatch "
 						    "for auth method");
@@ -2346,19 +2129,19 @@
 					 * For interoperability with Win2k,
 					 * we set the Vendor ID to "GSSAPI".
 					 */
-					cur_rmconf->spspec->vendorid =
+					cur_rmconf->prhead->spspec->vendorid =
 					    VENDORID_GSSAPI;
 					break;
 				case algtype_rsasig:
-					if (oakley_get_certtype(cur_rmconf->peerscert) == ISAKMP_CERT_PLAINRSA) {
+					if (cur_rmconf->certtype == ISAKMP_CERT_PLAINRSA) {
 						if (rsa_list_count(cur_rmconf->rsa_private) == 0) {
 							yyerror ("Private PlainRSA key not set. "
-								 "Use directive 'certificate_type plainrsa ...'\n");
+								"Use directive 'certificate_type plainrsa ...'\n");
 							return -1;
 						}
 						if (rsa_list_count(cur_rmconf->rsa_public) == 0) {
 							yyerror ("Public PlainRSA keys not set. "
-								 "Use directive 'peers_certfile plainrsa ...'\n");
+								"Use directive 'peers_certfile plainrsa ...'\n");
 							return -1;
 						}
 					}
@@ -2388,6 +2171,32 @@
 	;
 %%
 
+static struct proposalspec *
+newprspec()
+{
+	struct proposalspec *new;
+
+	new = racoon_calloc(1, sizeof(*new));
+	if (new == NULL)
+		yyerror("failed to allocate proposal");
+
+	return new;
+}
+
+/*
+ * insert into head of list.
+ */
+static void
+insprspec(prspec, head)
+	struct proposalspec *prspec;
+	struct proposalspec **head;
+{
+	if (*head != NULL)
+		(*head)->prev = prspec;
+	prspec->next = *head;
+	*head = prspec;
+}
+
 static struct secprotospec *
 newspspec()
 {
@@ -2415,113 +2224,44 @@
  * insert into head of list.
  */
 static void
-insspspec(rmconf, spspec)
-	struct remoteconf *rmconf;
+insspspec(spspec, head)
 	struct secprotospec *spspec;
+	struct proposalspec **head;
 {
-	if (rmconf->spspec != NULL)
-		rmconf->spspec->prev = spspec;
-	spspec->next = rmconf->spspec;
-	rmconf->spspec = spspec;
-}
+	spspec->back = *head;
 
-static struct secprotospec *
-dupspspec(spspec)
-	struct secprotospec *spspec;
-{
-	struct secprotospec *new;
-
-	new = newspspec();
-	if (new == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "dupspspec: malloc failed\n");
-		return NULL;
-	}
-	memcpy(new, spspec, sizeof(*new));
-
-	if (spspec->gssid) {
-		new->gssid = racoon_strdup(spspec->gssid);
-		STRDUP_FATAL(new->gssid);
-	}
-	if (spspec->remote) {
-		new->remote = racoon_malloc(sizeof(*new->remote));
-		if (new->remote == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL, 
-			    "dupspspec: malloc failed (remote)\n");
-			return NULL;
-		}
-		memcpy(new->remote, spspec->remote, sizeof(*new->remote));
-	}
-
-	return new;
-}
-
-/*
- * copy the whole list
- */
-void
-dupspspec_list(dst, src)
-	struct remoteconf *dst, *src;
-{
-	struct secprotospec *p, *new, *last;
-
-	for(p = src->spspec, last = NULL; p; p = p->next, last = new) {
-		new = dupspspec(p);
-		if (new == NULL)
-			exit(1);
-
-		new->prev = last;
-		new->next = NULL; /* not necessary but clean */
-
-		if (last)
-			last->next = new;
-		else /* first element */
-			dst->spspec = new;
-
-	}
-}
-
-/*
- * delete the whole list
- */
-void
-flushspspec(rmconf)
-	struct remoteconf *rmconf;
-{
-	struct secprotospec *p;
-
-	while(rmconf->spspec != NULL) {
-		p = rmconf->spspec;
-		rmconf->spspec = p->next;
-		if (p->next != NULL)
-			p->next->prev = NULL; /* not necessary but clean */
-
-		if (p->gssid)
-			racoon_free(p->gssid);
-		if (p->remote)
-			racoon_free(p->remote);
-		racoon_free(p);
-	}
-	rmconf->spspec = NULL;
+	if ((*head)->spspec != NULL)
+		(*head)->spspec->prev = spspec;
+	spspec->next = (*head)->spspec;
+	(*head)->spspec = spspec;
 }
 
 /* set final acceptable proposal */
 static int
-set_isakmp_proposal(rmconf)
+set_isakmp_proposal(rmconf, prspec)
 	struct remoteconf *rmconf;
+	struct proposalspec *prspec;
 {
+	struct proposalspec *p;
 	struct secprotospec *s;
 	int prop_no = 1; 
 	int trns_no = 1;
 	int32_t types[MAXALGCLASS];
 
+	p = prspec;
+	if (p->next != 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"multiple proposal definition.\n");
+		return -1;
+	}
+
 	/* mandatory check */
-	if (rmconf->spspec == NULL) {
+	if (p->spspec == NULL) {
 		yyerror("no remote specification found: %s.\n",
 			saddr2str(rmconf->remote));
 		return -1;
 	}
-	for (s = rmconf->spspec; s != NULL; s = s->next) {
+	for (s = p->spspec; s != NULL; s = s->next) {
 		/* XXX need more to check */
 		if (s->algclass[algclass_isakmp_enc] == 0) {
 			yyerror("encryption algorithm required.");
@@ -2542,16 +2282,16 @@
 	}
 
 	/* skip to last part */
-	for (s = rmconf->spspec; s->next != NULL; s = s->next)
+	for (s = p->spspec; s->next != NULL; s = s->next)
 		;
 
 	while (s != NULL) {
 		plog(LLV_DEBUG2, LOCATION, NULL,
 			"lifetime = %ld\n", (long)
-			(s->lifetime ? s->lifetime : rmconf->lifetime));
+			(s->lifetime ? s->lifetime : p->lifetime));
 		plog(LLV_DEBUG2, LOCATION, NULL,
 			"lifebyte = %d\n",
-			s->lifebyte ? s->lifebyte : rmconf->lifebyte);
+			s->lifebyte ? s->lifebyte : p->lifebyte);
 		plog(LLV_DEBUG2, LOCATION, NULL,
 			"encklen=%d\n", s->encklen);
 
@@ -2566,8 +2306,8 @@
 		clean_tmpalgtype();
 		trns_no = expand_isakmpspec(prop_no, trns_no, types,
 				algclass_isakmp_enc, algclass_isakmp_ameth + 1,
-				s->lifetime ? s->lifetime : rmconf->lifetime,
-				s->lifebyte ? s->lifebyte : rmconf->lifebyte,
+				s->lifetime ? s->lifetime : p->lifetime,
+				s->lifebyte ? s->lifebyte : p->lifebyte,
 				s->encklen, s->vendorid, s->gssid,
 				rmconf);
 		if (trns_no == -1) {
@@ -2672,7 +2412,11 @@
 			}
 			memcpy(new->gssid->v, gssid, new->gssid->l);
 			racoon_free(gssid);
+#ifdef ENABLE_HYBRID
+		} else if (rmconf->xauth == NULL) {
+#else
 		} else {
+#endif
 			/*
 			 * Allocate the default ID so that it gets put
 			 * into a GSS ID attribute during the Phase 1
@@ -2687,6 +2431,30 @@
 	return trns_no;
 }
 
+static int
+listen_addr (struct sockaddr *addr, int udp_encap)
+{
+	struct myaddrs *p;
+
+	p = newmyaddr();
+	if (p == NULL) {
+		yyerror("failed to allocate myaddrs");
+		return -1;
+	}
+	p->addr = addr;
+	if (p->addr == NULL) {
+		yyerror("failed to copy sockaddr ");
+		delmyaddr(p);
+		return -1;
+	}
+	p->udp_encap = udp_encap;
+
+	insmyaddr(p, &lcconf->myaddrs);
+
+	lcconf->autograbaddr = 0;
+	return 0;
+}
+
 #if 0
 /*
  * fix lifebyte.
@@ -2711,7 +2479,6 @@
 {
 	int error;
 
-	yyerrorcount = 0;
 	yycf_init_buffer();
 
 	if (yycf_switch_buffer(lcconf->racoon_conf) != 0) {
diff --git a/src/racoon/cftoken.l b/src/racoon/cftoken.l
index 3042796..9950d49 100644
--- a/src/racoon/cftoken.l
+++ b/src/racoon/cftoken.l
@@ -1,4 +1,4 @@
-/*	$NetBSD: cftoken.l,v 1.23 2011/02/02 15:21:34 vanhu Exp $	*/
+/*	$NetBSD: cftoken.l,v 1.11.4.2 2007/09/03 18:07:29 mgrooms Exp $	*/
 
 /* Id: cftoken.l,v 1.53 2006/08/22 18:17:17 manubsd Exp */
 
@@ -132,7 +132,7 @@
 decstring	{digit}+
 hexstring	0x{hexdigit}+
 
-%s S_INI S_PRIV S_PTH S_LOG S_PAD S_LST S_RTRY S_CFG S_LDAP S_RAD
+%s S_INI S_PRIV S_PTH S_INF S_LOG S_PAD S_LST S_RTRY S_CFG S_LDAP
 %s S_ALGST S_ALGCL
 %s S_SAINF S_SAINFS
 %s S_RMT S_RMTS S_RMTP
@@ -174,8 +174,9 @@
 	/* include */
 <S_INI>include		{ YYDB; return(INCLUDE); }
 
-    /* pfkey_buffer */
-<S_INI>pfkey_buffer { YYDB; return(PFKEY_BUFFER); }
+	/* self information */
+<S_INI>identifier	{ BEGIN S_INF; YYDB; yywarn("it is obsoleted.  use \"my_identifier\" in each remote directives."); return(IDENTIFIER); }
+<S_INF>{semi}		{ BEGIN S_INI; return(EOS); }
 
 	/* special */
 <S_INI>complex_bundle	{ YYDB; return(COMPLEX_BUNDLE); }
@@ -188,6 +189,8 @@
 <S_LOG>info		{ YYD; yylval.num = LLV_INFO; return(LOGLEV); }
 <S_LOG>debug		{ YYD; yylval.num = LLV_DEBUG; return(LOGLEV); }
 <S_LOG>debug2		{ YYD; yylval.num = LLV_DEBUG2; return(LOGLEV); }
+<S_LOG>debug3		{ YYD; yywarn("it is obsoleted.  use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); }
+<S_LOG>debug4		{ YYD; yywarn("it is obsoleted.  use \"debug2\""); yylval.num = LLV_DEBUG2; return(LOGLEV); }
 <S_LOG>{semi}		{ BEGIN S_INI; return(EOS); }
 
 	/* padding */
@@ -211,15 +214,6 @@
 <S_LST>strict_address	{ YYD; return(STRICT_ADDRESS); }
 <S_LST>{ecl}		{ BEGIN S_INI; return(EOC); }
 
-	/* radius config */
-<S_INI>radiuscfg	{ BEGIN S_RAD; YYDB; return(RADCFG); }
-<S_RAD>{bcl}		{ return(BOC); }
-<S_RAD>auth		{ YYD; return(RAD_AUTH); }
-<S_RAD>acct		{ YYD; return(RAD_ACCT); }
-<S_RAD>timeout		{ YYD; return(RAD_TIMEOUT); }
-<S_RAD>retries		{ YYD; return(RAD_RETRIES); }
-<S_RAD>{ecl}		{ BEGIN S_INI; return(EOC); }
-
 	/* ldap config */
 <S_INI>ldapcfg		{ BEGIN S_LDAP; YYDB; return(LDAPCFG); }
 <S_LDAP>{bcl}		{ return(BOC); }
@@ -283,7 +277,6 @@
 	/* sainfo */
 <S_INI>sainfo		{ BEGIN S_SAINF; YYDB; return(SAINFO); }
 <S_SAINF>anonymous	{ YYD; return(ANONYMOUS); }
-<S_SAINF>clientaddr	{ YYD; return(CLIENTADDR); }
 <S_SAINF>{blcl}any{elcl}	{ YYD; return(PORTANY); }
 <S_SAINF>any		{ YYD; return(ANY); }
 <S_SAINF>from		{ YYD; return(FROM); }
@@ -294,6 +287,7 @@
 <S_SAINFS>{ecl}		{ BEGIN S_INI; return(EOC); }
 <S_SAINFS>pfs_group	{ YYD; return(PFS_GROUP); }
 <S_SAINFS>remoteid	{ YYD; return(REMOTEID); }
+<S_SAINFS>identifier	{ YYD; yywarn("it is obsoleted.  use \"my_identifier\"."); return(IDENTIFIER); }
 <S_SAINFS>my_identifier	{ YYD; return(MY_IDENTIFIER); }
 <S_SAINFS>lifetime	{ YYD; return(LIFETIME); }
 <S_SAINFS>time		{ YYD; return(LIFETYPE_TIME); }
@@ -310,7 +304,6 @@
 	/* remote spec */
 <S_RMT>{bcl}		{ BEGIN S_RMTS; return(BOC); }
 <S_RMTS>{ecl}		{ BEGIN S_INI; return(EOC); }
-<S_RMTS>remote_address	{ YYD; return(REMOTE_ADDRESS); }
 <S_RMTS>exchange_mode	{ YYD; return(EXCHANGE_MODE); }
 <S_RMTS>{comma}		{ YYD; /* XXX ignored, but to be handled. */ ; }
 <S_RMTS>base		{ YYD; yylval.num = ISAKMP_ETYPE_BASE; return(EXCHANGETYPE); }
@@ -322,6 +315,7 @@
 <S_RMTS>identity_only	{ YYD; yylval.num = IPSECDOI_SIT_IDENTITY_ONLY; return(SITUATIONTYPE); }
 <S_RMTS>secrecy		{ YYD; yylval.num = IPSECDOI_SIT_SECRECY; return(SITUATIONTYPE); }
 <S_RMTS>integrity	{ YYD; yylval.num = IPSECDOI_SIT_INTEGRITY; return(SITUATIONTYPE); }
+<S_RMTS>identifier	{ YYD; yywarn("it is obsoleted.  use \"my_identifier\"."); return(IDENTIFIER); }
 <S_RMTS>my_identifier	{ YYD; return(MY_IDENTIFIER); }
 <S_RMTS>xauth_login	{ YYD; return(XAUTH_LOGIN); /* formerly identifier type login */ }
 <S_RMTS>peers_identifier	{ YYD; return(PEERS_IDENTIFIER); }
@@ -335,12 +329,12 @@
 <S_RMTS>verify_cert	{ YYD; return(VERIFY_CERT); }
 <S_RMTS>send_cert	{ YYD; return(SEND_CERT); }
 <S_RMTS>send_cr		{ YYD; return(SEND_CR); }
-<S_RMTS>match_empty_cr	{ YYD; return(MATCH_EMPTY_CR); }
 <S_RMTS>dh_group	{ YYD; return(DH_GROUP); }
 <S_RMTS>nonce_size	{ YYD; return(NONCE_SIZE); }
 <S_RMTS>generate_policy	{ YYD; return(GENERATE_POLICY); }
 <S_RMTS>unique		{ YYD; yylval.num = GENERATE_POLICY_UNIQUE; return(GENERATE_LEVEL); }
 <S_RMTS>require		{ YYD; yylval.num = GENERATE_POLICY_REQUIRE; return(GENERATE_LEVEL); }
+<S_RMTS>support_mip6	{ YYD; yywarn("it is obsoleted.  use \"support_proxy\"."); return(SUPPORT_PROXY); }
 <S_RMTS>support_proxy	{ YYD; return(SUPPORT_PROXY); }
 <S_RMTS>initial_contact	{ YYD; return(INITIAL_CONTACT); }
 <S_RMTS>nat_traversal	{ YYD; return(NAT_TRAVERSAL); }
@@ -365,10 +359,8 @@
 <S_RMTS>script		{ YYD; return(SCRIPT); }
 <S_RMTS>phase1_up	{ YYD; return(PHASE1_UP); }
 <S_RMTS>phase1_down	{ YYD; return(PHASE1_DOWN); }
-<S_RMTS>phase1_dead	{ YYD; return(PHASE1_DEAD); }
 <S_RMTS>mode_cfg	{ YYD; return(MODE_CFG); }
 <S_RMTS>weak_phase1_check { YYD; return(WEAK_PHASE1_CHECK); }
-<S_RMTS>rekey		{ YYD; return(REKEY); }
 	/* remote proposal */
 <S_RMTS>proposal	{ BEGIN S_RMTP; YYDB; return(PROPOSAL); }
 <S_RMTP>{bcl}		{ return(BOC); }
@@ -435,7 +427,6 @@
 icmp6		{ YYD; yylval.num = IPPROTO_ICMPV6; return(UL_PROTO); }
 tcp		{ YYD; yylval.num = IPPROTO_TCP; return(UL_PROTO); }
 udp		{ YYD; yylval.num = IPPROTO_UDP; return(UL_PROTO); }
-gre		{ YYD; yylval.num = IPPROTO_GRE; return(UL_PROTO); }
 
 	/* algorithm type */
 des_iv64	{ YYD; yylval.num = algtype_des_iv64;	return(ALGORITHMTYPE); }
@@ -552,12 +543,14 @@
 
 
 	/* identifier type */
+vendor_id	{ YYD; yywarn("it is obsoleted."); return(VENDORID); }
 user_fqdn	{ YYD; yylval.num = IDTYPE_USERFQDN; return(IDENTIFIERTYPE); }
 fqdn		{ YYD; yylval.num = IDTYPE_FQDN; return(IDENTIFIERTYPE); }
 keyid		{ YYD; yylval.num = IDTYPE_KEYID; return(IDENTIFIERTYPE); }
 address		{ YYD; yylval.num = IDTYPE_ADDRESS; return(IDENTIFIERTYPE); }
 subnet		{ YYD; yylval.num = IDTYPE_SUBNET; return(IDENTIFIERTYPE); }
 asn1dn		{ YYD; yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); }
+certname	{ YYD; yywarn("certname will be obsoleted in near future."); yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); }
 
 	/* identifier qualifier */
 tag		{ YYD; yylval.num = IDQUAL_TAG;  return(IDENTIFIERQUAL); }
@@ -580,7 +573,7 @@
 			char *bp;
 
 			YYD;
-			yylval.num = strtoul(yytext, &bp, 10);
+			yylval.num = strtol(yytext, &bp, 10);
 			return(NUMBER);
 		}
 
@@ -638,10 +631,6 @@
 
 <<EOF>>		{
 			yy_delete_buffer(YY_CURRENT_BUFFER);
-			fclose (incstack[incstackp].fp);
-			incstack[incstackp].fp = NULL;
-			racoon_free(incstack[incstackp].path);
-			incstack[incstackp].path = NULL;
 			incstackp--;
     nextfile:
 			if (incstack[incstackp].matchon <
diff --git a/src/racoon/crypto_openssl.c b/src/racoon/crypto_openssl.c
index 215f4ef..811d0ef 100644
--- a/src/racoon/crypto_openssl.c
+++ b/src/racoon/crypto_openssl.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: crypto_openssl.c,v 1.20 2010/10/20 13:40:02 tteras Exp $	*/
+/*	$NetBSD: crypto_openssl.c,v 1.11.6.6 2009/04/29 10:50:25 tteras Exp $	*/
 
 /* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */
 
@@ -112,7 +112,6 @@
 #include "crypto_openssl.h"
 #include "debug.h"
 #include "gcmalloc.h"
-#include "isakmp.h"
 
 /*
  * I hate to cast every parameter to des_xx into void *, but it is
@@ -136,9 +135,9 @@
 	int len;
 {
 	X509_NAME *name;
-	char *buf, *dst;
+	char *buf;
 	char *field, *value;
-	int i;
+	int i, j;
 	vchar_t *ret = NULL;
 	caddr_t p;
 
@@ -154,38 +153,15 @@
 
 	name = X509_NAME_new();
 
-	dst = field = &buf[0];
+	field = &buf[0];
 	value = NULL;
 	for (i = 0; i < len; i++) {
-		if (buf[i] == '\\') {
-			/* Escape characters specified in RFC 2253 */
-			if (i < len - 1 &&
-			    strchr("\\,=+<>#;", buf[i+1]) != NULL) {
-				*dst++ = buf[++i];
-				continue;
-			} else if (i < len - 2) {
-				/* RFC 2253 hexpair character escape */
-				long u;
-				char esc_str[3];
-				char *endptr;
-
-				esc_str[0] = buf[++i];
-				esc_str[1] = buf[++i];
-				esc_str[2] = '\0';
-				u = strtol(esc_str, &endptr, 16);
-				if (*endptr != '\0' || u < 0 || u > 255)
-					goto err;
-				*dst++ = u;
-				continue;
-			} else
-				goto err;
-		}
 		if (!value && buf[i] == '=') {
-			*dst = '\0';
-			dst = value = &buf[i + 1];
+			buf[i] = '\0';
+			value = &buf[i + 1];
 			continue;
 		} else if (buf[i] == ',' || buf[i] == '/') {
-			*dst = '\0';
+			buf[i] = '\0';
 
 			plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
 			     field, value);
@@ -202,16 +178,16 @@
 				     "%s\n", eay_strerror());
 				goto err;
 			}
-
-			while (i + 1 < len && buf[i + 1] == ' ') i++;
-			dst = field = &buf[i + 1];
+			for (j = i + 1; j < len; j++) {
+				if (buf[j] != ' ')
+					break;
+			}
+			field = &buf[j];
 			value = NULL;
 			continue;
-		} else {
-			*dst++  = buf[i];
 		}
 	}
-	*dst = '\0';
+	buf[len] = '\0';
 
 	plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
 	     field, value);
@@ -462,7 +438,7 @@
 #ifdef ANDROID_CHANGES
 
 static BIO *BIO_from_android(char *path)
-{
+{       
 	void *data;
 	if (sscanf(path, pname, &data) == 1) {
 		return BIO_new_mem_buf(data, -1);
@@ -662,7 +638,7 @@
 }
 
 /*
- * get a subjectName from X509 certificate.
+ * get a subjectAltName from X509 certificate.
  */
 vchar_t *
 eay_get_x509asn1subjectname(cert)
@@ -673,6 +649,8 @@
 	vchar_t *name = NULL;
 	int len;
 
+	bp = (unsigned char *) cert->v;
+
 	x509 = mem2x509(cert);
 	if (x509 == NULL)
 		goto error;
@@ -806,46 +784,6 @@
 	return error;
 }
 
-/*
- * get a issuerName from X509 certificate.
- */
-vchar_t *
-eay_get_x509asn1issuername(cert)
-	vchar_t *cert;
-{
-	X509 *x509 = NULL;
-	u_char *bp;
-	vchar_t *name = NULL;
-	int len;
-
-	x509 = mem2x509(cert);
-	if (x509 == NULL)
-		goto error;
-
-	/* get the length of the name */
-	len = i2d_X509_NAME(x509->cert_info->issuer, NULL);
-	name = vmalloc(len);
-	if (name == NULL)
-		goto error;
-
-	/* get the name */
-	bp = (unsigned char *) name->v;
-	len = i2d_X509_NAME(x509->cert_info->issuer, &bp);
-
-	X509_free(x509);
-
-	return name;
-
-error:
-	plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
-
-	if (name != NULL)
-		vfree(name);
-	if (x509 != NULL)
-		X509_free(x509);
-
-	return NULL;
-}
 
 /*
  * decode a X509 certificate and make a readable text terminated '\n'.
@@ -912,9 +850,9 @@
     {
 	u_char *bp;
 
-	bp = (unsigned char *) cert->v + 1;
+	bp = (unsigned char *) cert->v;
 
-	x509 = d2i_X509(NULL, (void *)&bp, cert->l - 1);
+	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
     }
 #else
     {
@@ -924,7 +862,7 @@
 	bio = BIO_new(BIO_s_mem());
 	if (bio == NULL)
 		return NULL;
-	len = BIO_write(bio, cert->v + 1, cert->l - 1);
+	len = BIO_write(bio, cert->v, cert->l);
 	if (len == -1)
 		return NULL;
 	x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
@@ -978,13 +916,12 @@
 		return NULL;
 
 	len = i2d_X509(x509, NULL);
-	cert = vmalloc(len + 1);
+	cert = vmalloc(len);
 	if (cert == NULL) {
 		X509_free(x509);
 		return NULL;
 	}
-	cert->v[0] = ISAKMP_CERT_X509SIGN;
-	bp = (unsigned char *) &cert->v[1];
+	bp = (unsigned char *) cert->v;
 	error = i2d_X509(x509, &bp);
 	X509_free(x509);
 
@@ -1010,12 +947,17 @@
 	vchar_t *cert;
 {
 	X509 *x509;
+	u_char *bp;
 	EVP_PKEY *evp;
 	int res;
 
-	x509 = mem2x509(cert);
-	if (x509 == NULL)
+	bp = (unsigned char *) cert->v;
+
+	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
+	if (x509 == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL, "d2i_X509(): %s\n", eay_strerror());
 		return -1;
+	}
 
 	evp = X509_get_pubkey(x509);
 	if (! evp) {
@@ -1874,42 +1816,6 @@
 	return (caddr_t)c;
 }
 
-static vchar_t *eay_hmac_one(key, data, type)
-	vchar_t *key, *data;
-	const EVP_MD *type;
-{
-	vchar_t *res;
-
-	if ((res = vmalloc(EVP_MD_size(type))) == 0)
-		return NULL;
-
-	if (!HMAC(type, (void *) key->v, key->l,
-		  (void *) data->v, data->l, (void *) res->v, NULL)) {
-		vfree(res);
-		return NULL;
-	}
-
-	return res;
-}
-
-static vchar_t *eay_digest_one(data, type)
-	vchar_t *data;
-	const EVP_MD *type;
-{
-	vchar_t *res;
-
-	if ((res = vmalloc(EVP_MD_size(type))) == 0)
-		return NULL;
-
-	if (!EVP_Digest((void *) data->v, data->l,
-			(void *) res->v, NULL, type, NULL)) {
-		vfree(res);
-		return NULL;
-	}
-
-	return res;
-}
-
 #ifdef WITH_SHA2
 /*
  * HMAC SHA2-512
@@ -1918,7 +1824,14 @@
 eay_hmacsha2_512_one(key, data)
 	vchar_t *key, *data;
 {
-	return eay_hmac_one(key, data, EVP_sha2_512());
+	vchar_t *res;
+	caddr_t ctx;
+
+	ctx = eay_hmacsha2_512_init(key);
+	eay_hmacsha2_512_update(ctx, data);
+	res = eay_hmacsha2_512_final(ctx);
+
+	return(res);
 }
 
 caddr_t
@@ -1968,7 +1881,14 @@
 eay_hmacsha2_384_one(key, data)
 	vchar_t *key, *data;
 {
-	return eay_hmac_one(key, data, EVP_sha2_384());
+	vchar_t *res;
+	caddr_t ctx;
+
+	ctx = eay_hmacsha2_384_init(key);
+	eay_hmacsha2_384_update(ctx, data);
+	res = eay_hmacsha2_384_final(ctx);
+
+	return(res);
 }
 
 caddr_t
@@ -2018,7 +1938,14 @@
 eay_hmacsha2_256_one(key, data)
 	vchar_t *key, *data;
 {
-	return eay_hmac_one(key, data, EVP_sha2_256());
+	vchar_t *res;
+	caddr_t ctx;
+
+	ctx = eay_hmacsha2_256_init(key);
+	eay_hmacsha2_256_update(ctx, data);
+	res = eay_hmacsha2_256_final(ctx);
+
+	return(res);
 }
 
 caddr_t
@@ -2069,7 +1996,14 @@
 eay_hmacsha1_one(key, data)
 	vchar_t *key, *data;
 {
-	return eay_hmac_one(key, data, EVP_sha1());
+	vchar_t *res;
+	caddr_t ctx;
+
+	ctx = eay_hmacsha1_init(key);
+	eay_hmacsha1_update(ctx, data);
+	res = eay_hmacsha1_final(ctx);
+
+	return(res);
 }
 
 caddr_t
@@ -2119,7 +2053,14 @@
 eay_hmacmd5_one(key, data)
 	vchar_t *key, *data;
 {
-	return eay_hmac_one(key, data, EVP_md5());
+	vchar_t *res;
+	caddr_t ctx;
+
+	ctx = eay_hmacmd5_init(key);
+	eay_hmacmd5_update(ctx, data);
+	res = eay_hmacmd5_final(ctx);
+
+	return(res);
 }
 
 caddr_t
@@ -2205,7 +2146,14 @@
 eay_sha2_512_one(data)
 	vchar_t *data;
 {
-	return eay_digest_one(data, EVP_sha512());
+	caddr_t ctx;
+	vchar_t *res;
+
+	ctx = eay_sha2_512_init();
+	eay_sha2_512_update(ctx, data);
+	res = eay_sha2_512_final(ctx);
+
+	return(res);
 }
 
 int
@@ -2258,7 +2206,14 @@
 eay_sha2_384_one(data)
 	vchar_t *data;
 {
-	return eay_digest_one(data, EVP_sha2_384());
+	caddr_t ctx;
+	vchar_t *res;
+
+	ctx = eay_sha2_384_init();
+	eay_sha2_384_update(ctx, data);
+	res = eay_sha2_384_final(ctx);
+
+	return(res);
 }
 
 int
@@ -2311,7 +2266,14 @@
 eay_sha2_256_one(data)
 	vchar_t *data;
 {
-	return eay_digest_one(data, EVP_sha2_256());
+	caddr_t ctx;
+	vchar_t *res;
+
+	ctx = eay_sha2_256_init();
+	eay_sha2_256_update(ctx, data);
+	res = eay_sha2_256_final(ctx);
+
+	return(res);
 }
 
 int
@@ -2363,7 +2325,14 @@
 eay_sha1_one(data)
 	vchar_t *data;
 {
-	return eay_digest_one(data, EVP_sha1());
+	caddr_t ctx;
+	vchar_t *res;
+
+	ctx = eay_sha1_init();
+	eay_sha1_update(ctx, data);
+	res = eay_sha1_final(ctx);
+
+	return(res);
 }
 
 int
@@ -2414,7 +2383,14 @@
 eay_md5_one(data)
 	vchar_t *data;
 {
-	return eay_digest_one(data, EVP_md5());
+	caddr_t ctx;
+	vchar_t *res;
+
+	ctx = eay_md5_init();
+	eay_md5_update(ctx, data);
+	res = eay_md5_final(ctx);
+
+	return(res);
 }
 
 int
diff --git a/src/racoon/crypto_openssl.h b/src/racoon/crypto_openssl.h
index 66fac73..9a17de8 100644
--- a/src/racoon/crypto_openssl.h
+++ b/src/racoon/crypto_openssl.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: crypto_openssl.h,v 1.7 2009/08/17 11:59:10 vanhu Exp $	*/
+/*	$NetBSD: crypto_openssl.h,v 1.5 2006/10/06 12:02:27 manu Exp $	*/
 
 /* Id: crypto_openssl.h,v 1.11 2004/11/13 11:28:01 manubsd Exp */
 
@@ -34,6 +34,8 @@
 #ifndef _CRYPTO_OPENSSL_H
 #define _CRYPTO_OPENSSL_H
 
+#include "crypto_openssl.h"
+
 #include <openssl/x509v3.h>
 #include <openssl/rsa.h>
 
@@ -53,7 +55,6 @@
 extern int eay_check_x509cert __P((vchar_t *, char *, char *, int));
 extern vchar_t *eay_get_x509asn1subjectname __P((vchar_t *));
 extern int eay_get_x509subjectaltname __P((vchar_t *, char **, int *, int));
-extern vchar_t * eay_get_x509asn1issuername __P((vchar_t *));
 extern char *eay_get_x509text __P((vchar_t *));
 extern vchar_t *eay_get_x509cert __P((char *));
 extern vchar_t *eay_get_x509sign __P((vchar_t *, vchar_t *));
diff --git a/src/racoon/debug.h b/src/racoon/debug.h
index 4270b6a..47c2641 100644
--- a/src/racoon/debug.h
+++ b/src/racoon/debug.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: debug.h,v 1.5 2008/12/23 14:03:12 tteras Exp $	*/
+/*	$NetBSD: debug.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: debug.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */
 
@@ -37,6 +37,5 @@
 /* define by main.c */
 extern int f_local;
 extern int vflag;
-extern int dump_config;
 
 #endif /* _DEBUG_H */
diff --git a/src/racoon/dnssec.c b/src/racoon/dnssec.c
index d52a243..1fc0bd1 100644
--- a/src/racoon/dnssec.c
+++ b/src/racoon/dnssec.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: dnssec.c,v 1.5 2009/03/12 10:57:26 tteras Exp $	*/
+/*	$NetBSD: dnssec.c,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /*	$KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $	*/
 
@@ -55,11 +55,11 @@
 
 extern int h_errno;
 
-vchar_t *
+cert_t *
 dnssec_getcert(id)
 	vchar_t *id;
 {
-	vchar_t *cert = NULL;
+	cert_t *cert = NULL;
 	struct certinfo *res = NULL;
 	struct ipsecdoi_id_b *id_b;
 	int type;
@@ -116,22 +116,39 @@
 	}
 
 	/* create cert holder */
-	cert = vmalloc(res->ci_certlen + 1);
+	cert = oakley_newcert();
 	if (cert == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to get cert buffer.\n");
 		goto err;
 	}
-	cert->v[0] = type;
-	memcpy(&cert->v[1], res->ci_cert, res->ci_certlen);
+	cert->pl = vmalloc(res->ci_certlen + 1);
+	if (cert->pl == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get cert buffer.\n");
+		goto err;
+	}
+	memcpy(cert->pl->v + 1, res->ci_cert, res->ci_certlen);
+	cert->pl->v[0] = type;
+	cert->cert.v = cert->pl->v + 1;
+	cert->cert.l = cert->pl->l - 1;
 
 	plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
-	plogdump(LLV_DEBUG, cert->v, cert->l);
+	plogdump(LLV_DEBUG, cert->pl->v, cert->pl->l);
+
+end:
+	if (res)
+		freecertinfo(res);
+
+	return cert;
 
 err:
 	if (name)
 		racoon_free(name);
-	if (res)
-		freecertinfo(res);
-	return cert;
+	if (cert) {
+		oakley_delcert(cert);
+		cert = NULL;
+	}
+
+	goto end;
 }
diff --git a/src/racoon/dnssec.h b/src/racoon/dnssec.h
index 1a03d77..fb1c931 100644
--- a/src/racoon/dnssec.h
+++ b/src/racoon/dnssec.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: dnssec.h,v 1.5 2009/03/12 10:57:26 tteras Exp $	*/
+/*	$NetBSD: dnssec.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: dnssec.h,v 1.3 2004/06/11 16:00:16 ludvigm Exp */
 
@@ -34,6 +34,6 @@
 #ifndef _DNSSEC_H
 #define _DNSSEC_H
 
-extern vchar_t *dnssec_getcert __P((vchar_t *));
+extern cert_t *dnssec_getcert __P((vchar_t *));
 
 #endif /* _DNSSEC_H */
diff --git a/src/racoon/doc/FAQ b/src/racoon/doc/FAQ
index cf9c394..0ab49f0 100644
--- a/src/racoon/doc/FAQ
+++ b/src/racoon/doc/FAQ
@@ -18,7 +18,7 @@
 
 A:
 	Configure both ends exactly the same.  With just a tiny little
-	difference, you will be in trouble.
+	differnce, you will be in trouble.
 
 Q: How to build racoon on my platform?
 
@@ -109,6 +109,6 @@
 Q: Other documents to look at?
 
 A:
-	http://www.NetBSD.org/docs/network/ipsec/
+	http://www.netbsd.org/Documentation/network/ipsec/
 	http://www.kame.net/
 	http://www.kame.net/newsletter/
diff --git a/src/racoon/doc/README.privsep b/src/racoon/doc/README.privsep
deleted file mode 100644
index e01c820..0000000
--- a/src/racoon/doc/README.privsep
+++ /dev/null
@@ -1,152 +0,0 @@
-		Using Racoon with Privilege Separation
-		     Tue Mar 25 16:37:09 MDT 2008
-
-
-Racoon can run in a chroot'd environment.  When so instructed, it runs as two
-processes, one of which handles a small number of simple requests and runs as
-root in the full native filesystem, and another which runs as a less
-privileged user in a chroot'd environment and which handles all the other and
-very complex business of racoon.
-
-Because racoon does many complex things there are many opportunities for
-coding errors to lead to compromises and so this separation is important.  If
-someone breaks into your system using racoon and you have enabled privilege
-separation, they will find themselves in a very limited environment and unable
-to do much damage.  They may be able to alter the host's security associations
-or obtain the private keys stored on that system using file descriptors
-available to the unprivileged instance of racoon, and from there they will be
-able to alter security associations on other hosts in disruptive or dangerous
-ways if you have generate_policy enabled on those hosts.  But that's because
-in its current form generate_policy is itself dangerous and requires that you
-trust anyone with the credentials to use it.
-
-They will also be able to execute any scripts you have placed in the scripts
-directory, although racoon will prevent them from mis-using the traditional
-environment variables PATH, LD_LIBRARY_PATH, and IFS.  But if you have
-introduced vulnerabilities into your scripts you may want to re-visit them.
-The thing to watch for is blindly trusting the environment variables passed
-in by racoon - assume they could be set to anything by a malicious entity and
-check them for suitability before using them.
-
-All these possibilities are present when privilege separation is not enabled,
-and they are greatly reduced when it is enabled because the resources
-available to the attacker are less.
-
-*****
-
-The basic concept with racoon's privilege separation is that a minimal
-environment containing all the files racoon needs to operate - with the
-exception of private keys, scripts, and system-wide authentication services -
-is placed in a stripped-down copy of the original environment.  The private
-keys and scripts are left in the original environment where only the
-privileged instance of racoon will have access to them.
-
-Here are basic instructions for setting up racoon to run with privilege
-separation:
-
-
-First, create a user/group for racoon to run under.  For example, user:group
-ike:ike.  The account should not have a usable password or real home
-directory, so copy the general format of another system-services type account
-such as 'daemon'.
-
-You already have files in, e.g. /usr/local/etc/racoon - perhaps racoon.conf, a
-certs directory containing certificates, a scripts directory, and other
-miscellaneous files such as welcome messages.  Perform the following steps:
-
-cd /usr/local/etc/racoon
-mkdir root
-mv certs root
-mkdir certs
-mv root/certs/*.key certs
-
-If you want to be able to switch back and forth between using and not using
-privsep, do this too:
-
-cd /usr/local/etc/racoon/certs
-for i in ../root/certs/*
-do
-	ln -s $i .
-done
-
-Now root/certs contains certificates and certs contains the keys.  The idea is
-that the public certificates are in the chroot'd area
-(/usr/local/etc/racoon/root) and the keys are available only to the privileged
-instance of racoon.
-
-Move any other racoon configuration data into /usr/local/etc/racoon/root,
-with the exception of the scripts directory and racoon.conf.
-
-All the files in /usr/local/etc/racoon/root should be owned by root and the
-ike:ike user you created should not have write access to any directories or
-files (unless you are using something like 'path backupsa', but you get the
-idea).
-
-Create the device nodes:
-
-mkdir root/dev
-
-Do whatever your OS requires to populate the new dev directory with a
-minimal set of devices, e.g. mknod, MAKEDEV, or mount devfs...  In freebsd
-this is done by adding a line to /etc/fstab:
-
-devfs	/usr/local/etc/racoon/root/dev	devfs	rw		0	0
-
-and then adding a line like this to /etc/rc.conf:
-
-devfs_set_rulesets="/usr/local/etc/racoon/root/dev=devfsrules_basic"
-
-and then adding the following lines to /etc/devfs.rules:
-
-[devfsrules_basic=10]
-add include $devfsrules_hide_all
-add include $devfsrules_unhide_basic
-
-and then either rebooting or entering "mount -a && /etc/rc.d/devfs start".
-
-When done with that:
-
-mkdir -p root/usr/local/etc
-ln -s ../../../ root/usr/local/etc/racoon
-
-This dummy hierarchy keeps the config file consistent between both copies of
-racoon. Of course, you could actually put the certs directory and any other
-configuration data down in the hierarchy but I prefer to leave it at the root
-and link to it as shown.  You may end up with something like this:
-
-root# ls -FC /usr/local/etc/racoon/root
-certs/	dev/	usr/
-
-root# ls -l /usr/local/etc/racoon/root/usr/local/etc
-lrwxr-xr-x  1 root  wheel  9 Mar  7 22:13 racoon -> ../../../
-
-root# ls -FC /usr/local/etc/racoon/root/usr/local/etc/racoon/
-certs/	dev/	usr/
-
-Presumably your racoon.conf already contains something like:
-
-path certificate "/usr/local/etc/racoon/certs";
-path script "/usr/local/etc/racoon/scripts";
-
-If so, great. If not, add them. Then, finally, add the privsep section:
-
-privsep {
-	user "ike";
-	group "ike";
-	chroot "/usr/local/etc/racoon/root";
-}
-
-Apply the patches posted to the list and rebuild racoon (the patches will be
-incorporated into the release subsequent to the date of this memo, so if you
-use that or a later release you can skip this step).
-
-Restart racoon and hopefully things will work.  As of the date of this memo,
-re-loading the configuration file with racoonctl will not work with privsep
-enabled.  However, the problem is not insurmountable and if you figure it out
-let us know.
-
-I have not tested privsep with many of racoon's features such as XAUTH or
-scripts, so if you have trouble with them and work anything out please reply
-to the list so that your discoveries may be incorporated into this document.
-
-Last modified: $Date: 2008/03/28 04:18:52 $
diff --git a/src/racoon/eaytest.c b/src/racoon/eaytest.c
index 1474bdc..323ecef 100644
--- a/src/racoon/eaytest.c
+++ b/src/racoon/eaytest.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: eaytest.c,v 1.10 2010/01/17 23:02:48 wiz Exp $	*/
+/*	$NetBSD: eaytest.c,v 1.7.6.2 2008/07/15 00:55:48 mgrooms Exp $	*/
 
 /* Id: eaytest.c,v 1.22 2005/06/19 18:02:54 manubsd Exp */
 
@@ -572,7 +572,6 @@
 
 		n++;
 	}
-	closedir(dirp);
 
 	p = (char **)realloc(certs, (n + 1) * sizeof(certs));
 	if (p == NULL)
diff --git a/src/racoon/evt.c b/src/racoon/evt.c
index 11d9695..fc65b20 100644
--- a/src/racoon/evt.c
+++ b/src/racoon/evt.c
@@ -1,10 +1,9 @@
-/*	$NetBSD: evt.c,v 1.10 2010/10/21 06:15:28 tteras Exp $	*/
+/*	$NetBSD: evt.c,v 1.5 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
- * Copyright (C) 2008 Timo Teras
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -47,55 +46,14 @@
 #include "plog.h"
 #include "misc.h"
 #include "admin.h"
-#include "handler.h"
-#include "session.h"
 #include "gcmalloc.h"
 #include "evt.h"
-#include "var.h"
 
 #ifdef ENABLE_ADMINPORT
+struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
+int evtlist_len = 0;
 
-static EVT_LISTENER_LIST(evt_listeners);
-
-struct evt_message {
-	struct admin_com adm;
-	struct evt_async evt;
-};
-
-struct evt {
-	struct evtdump *dump;
-	TAILQ_ENTRY(evt) next;
-};
-
-TAILQ_HEAD(evtlist, evt);
-
-#define EVTLIST_MAX	32
-
-static struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
-static int evtlist_len = 0;
-static int evtlist_inuse = 0;
-
-static struct {
-	int newtype, oldtype;
-} evttype_map[] = {
-	{ EVT_RACOON_QUIT,		EVTT_RACOON_QUIT },
-	{ EVT_PHASE1_UP,		EVTT_PHASE1_UP },
-	{ EVT_PHASE1_DOWN,		EVTT_PHASE1_DOWN },
-	{ EVT_PHASE1_NO_RESPONSE,	EVTT_PEER_NO_RESPONSE },
-	{ EVT_PHASE1_NO_PROPOSAL,	EVTT_PEERPH1_NOPROP },
-	{ EVT_PHASE1_AUTH_FAILED,	EVTT_PEERPH1AUTH_FAILED },
-	{ EVT_PHASE1_DPD_TIMEOUT,	EVTT_DPD_TIMEOUT },
-	{ EVT_PHASE1_PEER_DELETED,	EVTT_PEER_DELETE },
-	{ EVT_PHASE1_MODE_CFG,		EVTT_ISAKMP_CFG_DONE },
-	{ EVT_PHASE1_XAUTH_SUCCESS,	EVTT_XAUTH_SUCCESS },
-	{ EVT_PHASE1_XAUTH_FAILED,	EVTT_XAUTH_FAILED },
-	{ EVT_PHASE2_NO_PHASE1,		-1 },
-	{ EVT_PHASE2_UP,		EVTT_PHASE2_UP },
-	{ EVT_PHASE2_DOWN,		EVTT_PHASE2_DOWN },
-	{ EVT_PHASE2_NO_RESPONSE,	EVTT_PEER_NO_RESPONSE },
-};
-
-static void
+void
 evt_push(src, dst, type, optdata)
 	struct sockaddr *src;
 	struct sockaddr *dst;
@@ -105,21 +63,9 @@
 	struct evtdump *evtdump;
 	struct evt *evt;
 	size_t len;
-	int i;
 
 	/* If admin socket is disabled, silently discard anything */
-	if (adminsock_path == NULL || !evtlist_inuse)
-		return;
-
-	/* Map the event type to old */
-	for (i = 0; i < sizeof(evttype_map) / sizeof(evttype_map[0]); i++)
-		if (evttype_map[i].newtype == type)
-			break;
-	if (i >= sizeof(evttype_map) / sizeof(evttype_map[0]))
-		return;
-
-	type = evttype_map[i].oldtype;
-	if (type < 0)
+	if (adminsock_path == NULL)
 		return;
 
 	/* If we are above the limit, don't record anything */
@@ -175,7 +121,7 @@
 	return;
 }
 
-static struct evtdump *
+struct evtdump *
 evt_pop(void) {
 	struct evtdump *evtdump;
 	struct evt *evt;
@@ -196,12 +142,6 @@
 	struct evtdump *evtdump;
 	vchar_t *buf = NULL;
 
-	if (!evtlist_inuse) {
-		evtlist_inuse = 1;
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "evt_dump: deprecated event polling used\n");
-	}
-
 	if ((evtdump = evt_pop()) != NULL) {
 		if ((buf = vmalloc(evtdump->len)) == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL, 
@@ -215,185 +155,4 @@
 	return buf;
 }
 
-static struct evt_message *
-evtmsg_create(type, optdata)
-	int type;
-	vchar_t *optdata;
-{
-	struct evt_message *e;
-	size_t len;
-
-	len = sizeof(struct evt_message);
-	if (optdata != NULL)
-		len += optdata->l;
-
-	if ((e = racoon_malloc(len)) == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate event: %s\n",
-		     strerror(errno));
-		return NULL;
-	}
-
-	memset(e, 0, sizeof(struct evt_message));
-	e->adm.ac_len = len;
-	e->adm.ac_cmd = ADMIN_SHOW_EVT;
-	e->adm.ac_errno = 0;
-	e->adm.ac_proto = 0;
-	e->evt.ec_type = type;
-	time(&e->evt.ec_timestamp);
-	if (optdata != NULL)
-		memcpy(e + 1, optdata->v, optdata->l);
-
-	return e;
-}
-
-static void
-evt_unsubscribe(l)
-	struct evt_listener *l;
-{
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "[%d] admin connection released\n", l->fd);
-
-	LIST_REMOVE(l, ll_chain);
-	unmonitor_fd(l->fd);
-	close(l->fd);
-	racoon_free(l);
-}
-
-static int
-evt_unsubscribe_cb(ctx, fd)
-	void *ctx;
-	int fd;
-{
-	evt_unsubscribe((struct evt_listener *) ctx);
-	return 0;
-}
-
-static void
-evtmsg_broadcast(ll, e)
-	const struct evt_listener_list *ll;
-	struct evt_message *e;
-{
-	struct evt_listener *l, *nl;
-
-	for (l = LIST_FIRST(ll); l != NULL; l = nl) {
-		nl = LIST_NEXT(l, ll_chain);
-
-		if (send(l->fd, e, e->adm.ac_len, MSG_DONTWAIT) < 0) {
-			plog(LLV_DEBUG, LOCATION, NULL, "Cannot send event to fd: %s\n",
-				strerror(errno));
-			evt_unsubscribe(l);
-		}
-	}
-}
-
-void
-evt_generic(type, optdata)
-	int type;
-	vchar_t *optdata;
-{
-	struct evt_message *e;
-
-	if ((e = evtmsg_create(type, optdata)) == NULL)
-		return;
-
-	evtmsg_broadcast(&evt_listeners, e);
-	evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
-
-	racoon_free(e);
-}
-
-void
-evt_phase1(ph1, type, optdata)
-	const struct ph1handle *ph1;
-	int type;
-	vchar_t *optdata;
-{
-	struct evt_message *e;
-
-	if ((e = evtmsg_create(type, optdata)) == NULL)
-		return;
-
-	if (ph1->local)
-		memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local));
-	if (ph1->remote)
-		memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote));
-
-	evtmsg_broadcast(&ph1->evt_listeners, e);
-	evtmsg_broadcast(&evt_listeners, e);
-	evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
-
-	racoon_free(e);
-}
-
-void
-evt_phase2(ph2, type, optdata)
-	const struct ph2handle *ph2;
-	int type;
-	vchar_t *optdata;
-{
-	struct evt_message *e;
-	struct ph1handle *ph1 = ph2->ph1;
-
-	if ((e = evtmsg_create(type, optdata)) == NULL)
-		return;
-
-	if (ph1) {
-		if (ph1->local)
-			memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local));
-		if (ph1->remote)
-			memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote));
-	}
-	e->evt.ec_ph2msgid = ph2->msgid;
-
-	evtmsg_broadcast(&ph2->evt_listeners, e);
-	if (ph1)
-		evtmsg_broadcast(&ph1->evt_listeners, e);
-	evtmsg_broadcast(&evt_listeners, e);
-	evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
-
-	racoon_free(e);
-}
-
-int
-evt_subscribe(list, fd)
-	struct evt_listener_list *list;
-	int fd;
-{
-	struct evt_listener *l;
-
-	if ((l = racoon_malloc(sizeof(*l))) == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "Cannot allocate event listener: %s\n",
-		     strerror(errno));
-		return errno;
-	}
-
-	if (list == NULL)
-		list = &evt_listeners;
-
-	LIST_INSERT_HEAD(list, l, ll_chain);
-	l->fd = fd;
-	monitor_fd(l->fd, evt_unsubscribe_cb, l, 0);
-
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "[%d] admin connection is polling events\n", fd);
-
-	return -2;
-}
-
-void
-evt_list_init(list)
-	struct evt_listener_list *list;
-{
-	LIST_INIT(list);
-}
-
-void
-evt_list_cleanup(list)
-	struct evt_listener_list *list;
-{
-	while (!LIST_EMPTY(list))
-		evt_unsubscribe(LIST_FIRST(list));
-}
-
 #endif /* ENABLE_ADMINPORT */
diff --git a/src/racoon/evt.h b/src/racoon/evt.h
index 42e14d7..88ee366 100644
--- a/src/racoon/evt.h
+++ b/src/racoon/evt.h
@@ -1,10 +1,9 @@
-/*	$NetBSD: evt.h,v 1.7 2008/12/23 14:03:12 tteras Exp $	*/
+/*	$NetBSD: evt.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: evt.h,v 1.5 2006/01/19 10:24:09 fredsen Exp */
 
 /*
  * Copyright (C) 2004 Emmanuel Dreyfus
- * Copyright (C) 2008 Timo Teras
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -35,10 +34,6 @@
 #ifndef _EVT_H
 #define _EVT_H
 
-/*
- * Old style (deprecated) events which are polled.
- */
-
 struct evtdump {
 	size_t len;	
 	struct sockaddr_storage src;
@@ -69,78 +64,25 @@
 #define EVTT_PEERPH1_NOPROP	14	/* NO_PROPOSAL_CHOSEN & friends */
 #define EVTT_NO_ISAKMP_CFG	15	/* no need to wait for mode_cfg */
 
-/*
- * New style, asynchronous events.
- */
-
-struct evt_async {
-	uint32_t ec_type;
-	time_t ec_timestamp;
-
-	struct sockaddr_storage ec_ph1src;
-	struct sockaddr_storage ec_ph1dst;
-	u_int32_t ec_ph2msgid;
-
-	/*
-	 * Optionnal list of struct isakmp_data
-	 * for type EVTT_ISAKMP_CFG_DONE
-	 */
+struct evt {
+	struct evtdump *dump;
+	TAILQ_ENTRY(evt) next;
 };
 
-/* type */
-#define EVT_RACOON_QUIT			0x0001
+TAILQ_HEAD(evtlist, evt);
 
-#define EVT_PHASE1_UP			0x0100
-#define EVT_PHASE1_DOWN			0x0101
-#define EVT_PHASE1_NO_RESPONSE		0x0102
-#define EVT_PHASE1_NO_PROPOSAL		0x0103
-#define EVT_PHASE1_AUTH_FAILED		0x0104
-#define EVT_PHASE1_DPD_TIMEOUT		0x0105
-#define EVT_PHASE1_PEER_DELETED		0x0106
-#define EVT_PHASE1_MODE_CFG		0x0107
-#define EVT_PHASE1_XAUTH_SUCCESS	0x0108
-#define EVT_PHASE1_XAUTH_FAILED		0x0109
-
-#define EVT_PHASE2_NO_PHASE1		0x0200
-#define EVT_PHASE2_UP			0x0201
-#define EVT_PHASE2_DOWN			0x0202
-#define EVT_PHASE2_NO_RESPONSE		0x0203
+#define EVTLIST_MAX	32
 
 #ifdef ENABLE_ADMINPORT
+struct evtdump *evt_pop(void);
+vchar_t *evt_dump(void);
+void evt_push(struct sockaddr *, struct sockaddr *, int, vchar_t *);
+#endif
 
-struct ph1handle;
-struct ph2handle;
-
-struct evt_listener {
-	LIST_ENTRY(evt_listener) ll_chain;
-	int fd;
-};
-LIST_HEAD(evt_listener_list, evt_listener);
-#define EVT_LISTENER_LIST(x) struct evt_listener_list x
-
-void evt_generic __P((int type, vchar_t *optdata));
-void evt_phase1 __P((const struct ph1handle *ph1, int type, vchar_t *optdata));
-void evt_phase2 __P((const struct ph2handle *ph2, int type, vchar_t *optdata));
-vchar_t *evt_dump __P((void));
-
-int  evt_subscribe __P((struct evt_listener_list *list, int fd));
-void evt_list_init __P((struct evt_listener_list *list));
-void evt_list_cleanup __P((struct evt_listener_list *list));
-
+#ifdef ENABLE_ADMINPORT
+#define EVT_PUSH(src, dst, type, optdata) evt_push(src, dst, type, optdata);
 #else
-
-#define EVT_LISTENER_LIST(x)
-
-#define evt_generic(type, optdata) ;
-#define evt_phase1(ph1, type, optdata) ;
-#define evt_phase2(ph2, type, optdata) ;
-
-#define evt_subscribe(eventlist, fd) ;
-#define evt_list_init(eventlist) ;
-#define evt_list_cleanup(eventlist) ;
-#define evt_get_fdmask(nfds, fdset) nfds
-#define evt_handle_fdmask(fdset) ;
-
-#endif /* ENABLE_ADMINPORT */
+#define EVT_PUSH(src, dst, type, optdata) ;
+#endif
 
 #endif /* _EVT_H */
diff --git a/src/racoon/grabmyaddr.c b/src/racoon/grabmyaddr.c
index 29b913c..8155001 100644
--- a/src/racoon/grabmyaddr.c
+++ b/src/racoon/grabmyaddr.c
@@ -1,7 +1,9 @@
-/*	$NetBSD: grabmyaddr.c,v 1.28 2011/03/14 17:18:12 tteras Exp $	*/
+/*	$NetBSD: grabmyaddr.c,v 1.4.6.3 2008/06/18 07:30:18 mgrooms Exp $	*/
+
+/* Id: grabmyaddr.c,v 1.27 2006/04/06 16:27:05 manubsd Exp */
+
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2008 Timo Teras <timo.teras@iki.fi>.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -31,32 +33,40 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
 #include <sys/types.h>
-#include <sys/queue.h>
+#include <sys/param.h>
 #include <sys/socket.h>
+#include <sys/ioctl.h>
 
-#ifdef __linux__
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#define USE_NETLINK
-#else
-#include <net/route.h>
 #include <net/if.h>
-#include <net/if_dl.h>
-#include <sys/sysctl.h>
-#define USE_ROUTE
+#if defined(__FreeBSD__) && __FreeBSD__ >= 3
+#include <net/if_var.h>
 #endif
+#if defined(__NetBSD__) || defined(__FreeBSD__) ||	\
+  (defined(__APPLE__) && defined(__MACH__))
+#include <netinet/in.h>
+#include <netinet6/in6_var.h>
+#endif
+#include <net/route.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <netdb.h>
+#ifdef HAVE_GETIFADDRS
+#include <ifaddrs.h>
+#include <net/if.h>
+#endif 
 
 #include "var.h"
 #include "misc.h"
 #include "vmbuf.h"
 #include "plog.h"
 #include "sockmisc.h"
-#include "session.h"
 #include "debug.h"
 
 #include "localconf.h"
@@ -67,803 +77,841 @@
 #include "gcmalloc.h"
 #include "nattraversal.h"
 
-static int kernel_receive __P((void *ctx, int fd));
-static int kernel_open_socket __P((void));
-static void kernel_sync __P((void));
+#ifdef __linux__
+#include <linux/types.h>
+#include <linux/rtnetlink.h>
+#ifndef HAVE_GETIFADDRS
+#define HAVE_GETIFADDRS
+#define NEED_LINUX_GETIFADDRS
+#endif
+#endif
 
-struct myaddr {
-	LIST_ENTRY(myaddr) chain;
-	struct sockaddr_storage addr;
-	int fd;
-	int udp_encap;
+#ifndef HAVE_GETIFADDRS
+static unsigned int if_maxindex __P((void));
+#endif
+static struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *));
+static int suitable_ifaddr __P((const char *, const struct sockaddr *));
+#ifdef INET6
+static int suitable_ifaddr6 __P((const char *, const struct sockaddr *));
+#endif
+
+#ifdef NEED_LINUX_GETIFADDRS
+
+/* We could do this _much_ better. kame racoon in its current form
+ * will esentially die at frequent changes of address configuration.
+ */
+
+struct ifaddrs
+{
+	struct ifaddrs *ifa_next;
+	char		ifa_name[16];
+	int		ifa_ifindex;
+	struct sockaddr *ifa_addr;
+	struct sockaddr_storage ifa_addrbuf;
 };
 
-static LIST_HEAD(_myaddr_list_, myaddr) configured, opened;
-
-static void
-myaddr_delete(my)
-	struct myaddr *my;
+static int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
 {
-	if (my->fd != -1)
-		isakmp_close(my->fd);
-	LIST_REMOVE(my, chain);
-	racoon_free(my);
-}
-
-static int
-myaddr_configured(addr)
-	struct sockaddr *addr;
-{
-	struct myaddr *cfg;
-
-	if (LIST_EMPTY(&configured))
-		return TRUE;
-
-	LIST_FOREACH(cfg, &configured, chain) {
-		if (cmpsaddr(addr, (struct sockaddr *) &cfg->addr) <= CMPSADDR_WILDPORT_MATCH)
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
-static int
-myaddr_open(addr, udp_encap)
-	struct sockaddr *addr;
-	int udp_encap;
-{
-	struct myaddr *my;
-
-	/* Already open? */
-	LIST_FOREACH(my, &opened, chain) {
-		if (cmpsaddr(addr, (struct sockaddr *) &my->addr) <= CMPSADDR_WILDPORT_MATCH)
-			return TRUE;
-	}
-
-	my = racoon_calloc(1, sizeof(struct myaddr));
-	if (my == NULL)
-		return FALSE;
-
-	memcpy(&my->addr, addr, sysdep_sa_len(addr));
-	my->fd = isakmp_open(addr, udp_encap);
-	if (my->fd < 0) {
-		racoon_free(my);
-		return FALSE;
-	}
-	my->udp_encap = udp_encap;
-	LIST_INSERT_HEAD(&opened, my, chain);
-	return TRUE;
-}
-
-static int
-myaddr_open_all_configured(addr)
-	struct sockaddr *addr;
-{
-	/* create all configured, not already opened addresses */
-	struct myaddr *cfg, *my;
-
-	if (addr != NULL) {
-		switch (addr->sa_family) {
-		case AF_INET:
-#ifdef INET6
-		case AF_INET6:
-#endif
-			break;
-		default:
-			return FALSE;
-		}
-	}
-
-	LIST_FOREACH(cfg, &configured, chain) {
-		if (addr != NULL &&
-		    cmpsaddr(addr, (struct sockaddr *) &cfg->addr) > CMPSADDR_WILDPORT_MATCH)
-			continue;
-		if (!myaddr_open((struct sockaddr *) &cfg->addr, cfg->udp_encap))
-			return FALSE;
-	}
-	if (LIST_EMPTY(&configured)) {
-#ifdef ENABLE_HYBRID
-		/* Exclude any address we got through ISAKMP mode config */
-		if (exclude_cfg_addr(addr) == 0)
-			return FALSE;
-#endif
-		set_port(addr, lcconf->port_isakmp);
-		myaddr_open(addr, FALSE);
-#ifdef ENABLE_NATT
-		set_port(addr, lcconf->port_isakmp_natt);
-		myaddr_open(addr, TRUE);
-#endif
-	}
-	return TRUE;
-}
-
-static void
-myaddr_close_all_open(addr)
-	struct sockaddr *addr;
-{
-	/* delete all matching open sockets */
-	struct myaddr *my, *next;
-
-	for (my = LIST_FIRST(&opened); my; my = next) {
-		next = LIST_NEXT(my, chain);
-
-		if (cmpsaddr((struct sockaddr *) addr,
-			     (struct sockaddr *) &my->addr)
-		    <= CMPSADDR_WOP_MATCH)
-			myaddr_delete(my);
-	}
-}
-
-static void
-myaddr_flush_list(list)
-	struct _myaddr_list_ *list;
-{
-	struct myaddr *my, *next;
-
-	for (my = LIST_FIRST(list); my; my = next) {
-		next = LIST_NEXT(my, chain);
-		myaddr_delete(my);
-	}
-}
-
-void
-myaddr_flush()
-{
-	myaddr_flush_list(&configured);
-}
-
-int
-myaddr_listen(addr, udp_encap)
-	struct sockaddr *addr;
-	int udp_encap;
-{
-	struct myaddr *my;
-
-	if (sysdep_sa_len(addr) > sizeof(my->addr)) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "sockaddr size larger than sockaddr_storage\n");
-		return -1;
-	}
-
-	my = racoon_calloc(1, sizeof(struct myaddr));
-	if (my == NULL)
-		return -1;
-
-	memcpy(&my->addr, addr, sysdep_sa_len(addr));
-	my->udp_encap = udp_encap;
-	my->fd = -1;
-	LIST_INSERT_HEAD(&configured, my, chain);
-
-	return 0;
-}
-
-void
-myaddr_sync()
-{
-	struct myaddr *my, *next;
-
-	if (!lcconf->strict_address) {
-		kernel_sync();
-
-		/* delete all existing listeners which are not configured */
-		for (my = LIST_FIRST(&opened); my; my = next) {
-			next = LIST_NEXT(my, chain);
-
-			if (!myaddr_configured((struct sockaddr *) &my->addr))
-				myaddr_delete(my);
-		}
-	}
-}
-
-int
-myaddr_getfd(addr)
-        struct sockaddr *addr;
-{
-	struct myaddr *my;
-
-	LIST_FOREACH(my, &opened, chain) {
-		if (cmpsaddr((struct sockaddr *) &my->addr, addr) <= CMPSADDR_WILDPORT_MATCH)
-			return my->fd;
-	}
-
-	return -1;
-}
-
-int
-myaddr_getsport(addr)
-	struct sockaddr *addr;
-{
-	struct myaddr *my;
-
-	LIST_FOREACH(my, &opened, chain) {
-		if (cmpsaddr((struct sockaddr *) &my->addr, addr) <= CMPSADDR_WILDPORT_MATCH)
-			return extract_port((struct sockaddr *) &my->addr);
-	}
-
-	return PORT_ISAKMP;
-}
-
-void
-myaddr_init_lists()
-{
-	LIST_INIT(&configured);
-	LIST_INIT(&opened);
-}
-
-int
-myaddr_init()
-{
-        if (!lcconf->strict_address) {
-		lcconf->rtsock = kernel_open_socket();
-		if (lcconf->rtsock < 0)
-			return -1;
-		monitor_fd(lcconf->rtsock, kernel_receive, NULL, 0);
-	} else {
-		lcconf->rtsock = -1;
-		if (!myaddr_open_all_configured(NULL))
-			return -1;
-	}
-	return 0;
-}
-
-void
-myaddr_close()
-{
-	myaddr_flush_list(&configured);
-	myaddr_flush_list(&opened);
-	if (lcconf->rtsock != -1) {
-		unmonitor_fd(lcconf->rtsock);
-		close(lcconf->rtsock);
-	}
-}
-
-#if defined(USE_NETLINK)
-
-static int netlink_fd = -1;
-
-#define NLMSG_TAIL(nmsg) \
-	((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
-
-static void
-parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
-{
-	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
 	while (RTA_OK(rta, len)) {
 		if (rta->rta_type <= max)
 			tb[rta->rta_type] = rta;
 		rta = RTA_NEXT(rta,len);
 	}
+	return 0;
 }
 
-static int
-netlink_add_rtattr_l(struct nlmsghdr *n, int maxlen, int type,
-		     const void *data, int alen)
+static void recvaddrs(int fd, struct ifaddrs **ifa, __u32 seq)
 {
-	int len = RTA_LENGTH(alen);
-	struct rtattr *rta;
+	char	buf[8192];
+	struct sockaddr_nl nladdr;
+	struct iovec iov = { buf, sizeof(buf) };
+	struct ifaddrmsg *m;
+	struct rtattr * rta_tb[IFA_MAX+1];
+	struct ifaddrs *I;
 
-	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
-		return FALSE;
+	while (1) {
+		int status;
+		struct nlmsghdr *h;
 
-	rta = NLMSG_TAIL(n);
-	rta->rta_type = type;
-	rta->rta_len = len;
-	memcpy(RTA_DATA(rta), data, alen);
-	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
-	return TRUE;
+		struct msghdr msg = {
+			(void*)&nladdr, sizeof(nladdr),
+			&iov,	1,
+			NULL,	0,
+			0
+		};
+
+		status = recvmsg(fd, &msg, 0);
+
+		if (status < 0)
+			continue;
+
+		if (status == 0)
+			return;
+
+		if (nladdr.nl_pid) /* Message not from kernel */
+			continue;
+
+		h = (struct nlmsghdr*)buf;
+		while (NLMSG_OK(h, status)) {
+			if (h->nlmsg_seq != seq)
+				goto skip_it;
+
+			if (h->nlmsg_type == NLMSG_DONE)
+				return;
+
+			if (h->nlmsg_type == NLMSG_ERROR)
+				return;
+
+			if (h->nlmsg_type != RTM_NEWADDR)
+				goto skip_it;
+
+			m = NLMSG_DATA(h);
+
+			if (m->ifa_family != AF_INET &&
+			    m->ifa_family != AF_INET6)
+				goto skip_it;
+
+			if (m->ifa_flags&IFA_F_TENTATIVE)
+				goto skip_it;
+
+			memset(rta_tb, 0, sizeof(rta_tb));
+			parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(m), h->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
+
+			if (rta_tb[IFA_LOCAL] == NULL)
+				rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
+			if (rta_tb[IFA_LOCAL] == NULL)
+				goto skip_it;
+			
+			I = malloc(sizeof(struct ifaddrs));
+			if (!I)
+				return;
+			memset(I, 0, sizeof(*I));
+
+			I->ifa_ifindex = m->ifa_index;
+			I->ifa_addr = (struct sockaddr*)&I->ifa_addrbuf;
+			I->ifa_addr->sa_family = m->ifa_family;
+			if (m->ifa_family == AF_INET) {
+				struct sockaddr_in *sin = (void*)I->ifa_addr;
+				memcpy(&sin->sin_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 4);
+			} else {
+				struct sockaddr_in6 *sin = (void*)I->ifa_addr;
+				memcpy(&sin->sin6_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 16);
+				if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
+					sin->sin6_scope_id = I->ifa_ifindex;
+			}
+			I->ifa_next = *ifa;
+			*ifa = I;
+
+skip_it:
+			h = NLMSG_NEXT(h, status);
+		}
+		if (msg.msg_flags & MSG_TRUNC)
+			continue;
+	}
+	return;
 }
 
-static int
-netlink_enumerate(fd, family, type)
-	int fd;
-	int family;
-	int type;
+static int getifaddrs(struct ifaddrs **ifa0)
 {
 	struct {
 		struct nlmsghdr nlh;
 		struct rtgenmsg g;
 	} req;
-	struct sockaddr_nl addr;
-	static __u32 seq = 0;
-
-	memset(&addr, 0, sizeof(addr));
-	addr.nl_family = AF_NETLINK;
-
-	memset(&req, 0, sizeof(req));
-	req.nlh.nlmsg_len = sizeof(req);
-	req.nlh.nlmsg_type = type;
-	req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
-	req.nlh.nlmsg_pid = 0;
-	req.nlh.nlmsg_seq = ++seq;
-	req.g.rtgen_family = family;
-
-	return sendto(fd, (void *) &req, sizeof(req), 0,
-		      (struct sockaddr *) &addr, sizeof(addr)) >= 0;
-}
-
-static void
-netlink_add_del_address(int add, struct sockaddr *saddr)
-{
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "Netlink: address %s %s\n",
-	     saddrwop2str((struct sockaddr *) saddr),
-	     add ? "added" : "deleted");
-
-	if (add)
-		myaddr_open_all_configured(saddr);
-	else
-		myaddr_close_all_open(saddr);
-}
-
-#ifdef INET6
-static int
-netlink_process_addr(struct nlmsghdr *h)
-{
-	struct sockaddr_storage addr;
-	struct ifaddrmsg *ifa;
-	struct rtattr *rta[IFA_MAX+1];
-	struct sockaddr_in6 *sin6;
-
-	ifa = NLMSG_DATA(h);
-	parse_rtattr(rta, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h));
-
-	if (ifa->ifa_family != AF_INET6)
-		return 0;
-	if (ifa->ifa_flags & IFA_F_TENTATIVE)
-		return 0;
-	if (rta[IFA_LOCAL] == NULL)
-		rta[IFA_LOCAL] = rta[IFA_ADDRESS];
-	if (rta[IFA_LOCAL] == NULL)
-		return 0;
-
-	memset(&addr, 0, sizeof(addr));
-	addr.ss_family = ifa->ifa_family;
-	sin6 = (struct sockaddr_in6 *) &addr;
-	memcpy(&sin6->sin6_addr, RTA_DATA(rta[IFA_LOCAL]),
-		sizeof(sin6->sin6_addr));
-	if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
-		return 0;
-	sin6->sin6_scope_id = ifa->ifa_index;
-
-	netlink_add_del_address(h->nlmsg_type == RTM_NEWADDR,
-				(struct sockaddr *) &addr);
-
-	return 0;
-}
-#endif
-
-static int
-netlink_route_is_local(int family, const unsigned char *addr, size_t addr_len)
-{
-	struct {
-		struct nlmsghdr n;
-		struct rtmsg    r;
-		char            buf[1024];
-	} req;
-	struct rtmsg *r = NLMSG_DATA(&req.n);
-	struct rtattr *rta[RTA_MAX+1];
 	struct sockaddr_nl nladdr;
-	ssize_t rlen;
+	static __u32 seq;
+	struct ifaddrs *i;
+	int fd;
 
-	memset(&req, 0, sizeof(req));
-	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-	req.n.nlmsg_flags = NLM_F_REQUEST;
-	req.n.nlmsg_type = RTM_GETROUTE;
-	req.r.rtm_family = family;
-	netlink_add_rtattr_l(&req.n, sizeof(req), RTA_DST,
-			     addr, addr_len);
-	req.r.rtm_dst_len = addr_len * 8;
+	fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (fd < 0)
+		return -1;
 
 	memset(&nladdr, 0, sizeof(nladdr));
 	nladdr.nl_family = AF_NETLINK;
 
-	if (sendto(netlink_fd, &req, sizeof(req), 0,
-		   (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0)
-		return 0;
-	rlen = recv(netlink_fd, &req, sizeof(req), 0);
-	if (rlen < 0)
-		return 0;
+	req.nlh.nlmsg_len = sizeof(req);
+	req.nlh.nlmsg_type = RTM_GETADDR;
+	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+	req.nlh.nlmsg_pid = 0;
+	req.nlh.nlmsg_seq = ++seq;
+	req.g.rtgen_family = AF_UNSPEC;
 
-	return  req.n.nlmsg_type == RTM_NEWROUTE &&
-		req.r.rtm_type == RTN_LOCAL;
+	if (sendto(fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) {
+		close(fd);
+		return -1;
+	}
+
+	*ifa0 = NULL;
+
+	recvaddrs(fd, ifa0, seq);
+
+	close(fd);
+
+	fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+	for (i=*ifa0; i; i = i->ifa_next) {
+		struct ifreq ifr;
+		ifr.ifr_ifindex = i->ifa_ifindex;
+		ioctl(fd, SIOCGIFNAME, (void*)&ifr);
+		memcpy(i->ifa_name, ifr.ifr_name, 16);
+	}
+	close(fd);
+
+	return 0;
 }
 
-static int
-netlink_process_route(struct nlmsghdr *h)
+static void freeifaddrs(struct ifaddrs *ifa0)
 {
-	struct sockaddr_storage addr;
-	struct rtmsg *rtm;
-	struct rtattr *rta[RTA_MAX+1];
-	struct sockaddr_in *sin;
+        struct ifaddrs *i;
+
+        while (ifa0) {
+                i = ifa0;
+                ifa0 = i->ifa_next;
+                free(i);
+        }
+}
+
+#endif
+
+#ifndef HAVE_GETIFADDRS
+static unsigned int
+if_maxindex()
+{
+	struct if_nameindex *p, *p0;
+	unsigned int max = 0;
+
+	p0 = if_nameindex();
+	for (p = p0; p && p->if_index && p->if_name; p++) {
+		if (max < p->if_index)
+			max = p->if_index;
+	}
+	if_freenameindex(p0);
+	return max;
+}
+#endif
+
+void
+clear_myaddr(db)
+	struct myaddrs **db;
+{
+	struct myaddrs *p;
+
+	while (*db) {
+		p = (*db)->next;
+		delmyaddr(*db);
+		*db = p;
+	}
+}
+  
+static struct myaddrs *
+find_myaddr(db, p)
+	struct myaddrs *db;
+	struct myaddrs *p;
+{
+	struct myaddrs *q;
+	char h1[NI_MAXHOST], h2[NI_MAXHOST];
+
+	if (getnameinfo(p->addr, sysdep_sa_len(p->addr), h1, sizeof(h1), NULL, 0,
+	    NI_NUMERICHOST | niflags) != 0)
+		return NULL;
+
+	for (q = db; q; q = q->next) {
+		if (p->addr->sa_family != q->addr->sa_family)
+			continue;
+		if (getnameinfo(q->addr, sysdep_sa_len(q->addr), h2, sizeof(h2),
+		    NULL, 0, NI_NUMERICHOST | niflags) != 0)
+			return NULL;
+		if (strcmp(h1, h2) == 0)
+			return q;
+	}
+
+	return NULL;
+}
+
+void
+grab_myaddrs()
+{
+#ifdef HAVE_GETIFADDRS
+	struct myaddrs *p, *q, *old;
+	struct ifaddrs *ifa0, *ifap;
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 #endif
 
-	rtm = NLMSG_DATA(h);
+	char addr1[NI_MAXHOST];
 
-	/* local IP addresses get local route in the local table */
-	if (rtm->rtm_type != RTN_LOCAL ||
-	    rtm->rtm_table != RT_TABLE_LOCAL)
-		return 0;
+	if (getifaddrs(&ifa0)) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"getifaddrs failed: %s\n", strerror(errno));
+		exit(1);
+		/*NOTREACHED*/
+	}
 
-	parse_rtattr(rta, IFA_MAX, RTM_RTA(rtm), IFA_PAYLOAD(h));
-	if (rta[RTA_DST] == NULL)
- 		return 0;
+	old = lcconf->myaddrs;
 
-	/* setup the socket address */
-	memset(&addr, 0, sizeof(addr));
-	addr.ss_family = rtm->rtm_family;
-	switch (rtm->rtm_family) {
-	case AF_INET:
-		sin = (struct sockaddr_in *) &addr;
-		memcpy(&sin->sin_addr, RTA_DATA(rta[RTA_DST]),
-			sizeof(sin->sin_addr));
-		break;
+	for (ifap = ifa0; ifap; ifap = ifap->ifa_next) {
+		if (! ifap->ifa_addr)
+			continue;
+
+		if (ifap->ifa_addr->sa_family != AF_INET
 #ifdef INET6
-	case AF_INET6:
-		sin6 = (struct sockaddr_in6 *) &addr;
-		memcpy(&sin6->sin6_addr, RTA_DATA(rta[RTA_DST]),
-			sizeof(sin6->sin6_addr));
-		/* Link-local addresses are handled with RTM_NEWADDR
-		 * notifications */
-		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
-			return 0;
-		break;
+		 && ifap->ifa_addr->sa_family != AF_INET6
 #endif
-	default:
-		return 0;
-	}
+		)
+			continue;
 
-	/* If local route was deleted, check if there is still local
-	 * route for the same IP on another interface */
-	if (h->nlmsg_type == RTM_DELROUTE &&
-	    netlink_route_is_local(rtm->rtm_family,
-				   RTA_DATA(rta[RTA_DST]),
-				   RTA_PAYLOAD(rta[RTA_DST]))) {
-		plog(LLV_DEBUG, LOCATION, NULL,
-			"Netlink: not deleting %s yet, it exists still\n",
-			saddrwop2str((struct sockaddr *) &addr));
-		return 0;
-	}
-
-	netlink_add_del_address(h->nlmsg_type == RTM_NEWROUTE,
-				(struct sockaddr *) &addr);
-	return 0;
-}
-
-static int
-netlink_process(struct nlmsghdr *h)
-{
-	switch (h->nlmsg_type) {
-#ifdef INET6
-	case RTM_NEWADDR:
-	case RTM_DELADDR:
-		return netlink_process_addr(h);
-#endif
-	case RTM_NEWROUTE:
-	case RTM_DELROUTE:
-		return netlink_process_route(h);
-	}
-	return 0;
-}
-
-static int
-kernel_receive(ctx, fd)
-	void *ctx;
-	int fd;
-{
-	struct sockaddr_nl nladdr;
-	struct iovec iov;
-	struct msghdr msg = {
-		.msg_name = &nladdr,
-		.msg_namelen = sizeof(nladdr),
-		.msg_iov = &iov,
-		.msg_iovlen = 1,
-	};
-	struct nlmsghdr *h;
-	int len, status;
-	char buf[16*1024];
-
-	iov.iov_base = buf;
-	while (1) {
-		iov.iov_len = sizeof(buf);
-		status = recvmsg(fd, &msg, MSG_DONTWAIT);
-		if (status < 0) {
-			if (errno == EINTR)
-				continue;
-			if (errno == EAGAIN)
-				return FALSE;
+		if (!suitable_ifaddr(ifap->ifa_name, ifap->ifa_addr)) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"unsuitable address: %s %s\n",
+				ifap->ifa_name,
+				saddrwop2str(ifap->ifa_addr));
 			continue;
 		}
-		if (status == 0)
-			return FALSE;
 
-		h = (struct nlmsghdr *) buf;
-		while (NLMSG_OK(h, status)) {
-			netlink_process(h);
-			h = NLMSG_NEXT(h, status);
+		p = newmyaddr();
+		if (p == NULL) {
+			exit(1);
+			/*NOTREACHED*/
+		}
+		p->addr = dupsaddr(ifap->ifa_addr);
+		if (p->addr == NULL) {
+			exit(1);
+			/*NOTREACHED*/
+		}
+#ifdef INET6
+#ifdef __KAME__
+		if (ifap->ifa_addr->sa_family == AF_INET6) {
+			sin6 = (struct sockaddr_in6 *)p->addr;
+			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
+			 || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
+				sin6->sin6_scope_id =
+					ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
+				sin6->sin6_addr.s6_addr[2] = 0;
+				sin6->sin6_addr.s6_addr[3] = 0;
+			}
+		}
+#else /* !__KAME__ */
+		if (ifap->ifa_addr->sa_family == AF_INET6) {
+			sin6 = (struct sockaddr_in6 *)p->addr;
+			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
+			 || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
+				sin6->sin6_scope_id =
+					if_nametoindex(ifap->ifa_name);
+			}
+		}
+				
+#endif
+#endif
+		if (getnameinfo(p->addr, sysdep_sa_len(p->addr),
+				addr1, sizeof(addr1),
+				NULL, 0,
+				NI_NUMERICHOST | niflags))
+		strlcpy(addr1, "(invalid)", sizeof(addr1));
+		plog(LLV_DEBUG, LOCATION, NULL,
+			"my interface: %s (%s)\n",
+			addr1, ifap->ifa_name);
+		q = find_myaddr(old, p);
+		if (q)
+			p->sock = q->sock;
+		else
+			p->sock = -1;
+		p->next = lcconf->myaddrs;
+		lcconf->myaddrs = p;
+	}
+
+	freeifaddrs(ifa0);
+
+	clear_myaddr(&old);
+
+#else /*!HAVE_GETIFADDRS*/
+	int s;
+	unsigned int maxif;
+	int len;
+	struct ifreq *iflist;
+	struct ifconf ifconf;
+	struct ifreq *ifr, *ifr_end;
+	struct myaddrs *p, *q, *old;
+#ifdef INET6
+#ifdef __KAME__
+	struct sockaddr_in6 *sin6;
+#endif
+#endif
+
+	char addr1[NI_MAXHOST];
+
+	maxif = if_maxindex() + 1;
+	len = maxif * sizeof(struct sockaddr_storage) * 4; /* guess guess */
+
+	iflist = (struct ifreq *)racoon_malloc(len);
+	if (!iflist) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to allocate buffer\n");
+		exit(1);
+		/*NOTREACHED*/
+	}
+
+	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"socket(SOCK_DGRAM) failed: %s\n",
+			strerror(errno));
+		exit(1);
+		/*NOTREACHED*/
+	}
+	memset(&ifconf, 0, sizeof(ifconf));
+	ifconf.ifc_req = iflist;
+	ifconf.ifc_len = len;
+	if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) {
+		close(s);
+		plog(LLV_ERROR, LOCATION, NULL,
+			"ioctl(SIOCGIFCONF) failed: %s\n",
+			strerror(errno));
+		exit(1);
+		/*NOTREACHED*/
+	}
+	close(s);
+
+	old = lcconf->myaddrs;
+
+	/* Look for this interface in the list */
+	ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len);
+
+#define _IFREQ_LEN(p) \
+  (sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) > sizeof(struct ifreq) \
+    ? sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) : sizeof(struct ifreq))
+
+	for (ifr = ifconf.ifc_req;
+	     ifr < ifr_end;
+	     ifr = (struct ifreq *)((caddr_t)ifr + _IFREQ_LEN(ifr))) {
+
+		switch (ifr->ifr_addr.sa_family) {
+		case AF_INET:
+#ifdef INET6
+		case AF_INET6:
+#endif
+			if (!suitable_ifaddr(ifr->ifr_name, &ifr->ifr_addr)) {
+				plog(LLV_ERROR, LOCATION, NULL,
+					"unsuitable address: %s %s\n",
+					ifr->ifr_name,
+					saddrwop2str(&ifr->ifr_addr));
+				continue;
+			}
+
+			p = newmyaddr();
+			if (p == NULL) {
+				exit(1);
+				/*NOTREACHED*/
+			}
+			p->addr = dupsaddr(&ifr->ifr_addr);
+			if (p->addr == NULL) {
+				exit(1);
+				/*NOTREACHED*/
+			}
+#ifdef INET6
+#ifdef __KAME__
+			sin6 = (struct sockaddr_in6 *)p->addr;
+			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
+			 || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
+				sin6->sin6_scope_id =
+					ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
+				sin6->sin6_addr.s6_addr[2] = 0;
+				sin6->sin6_addr.s6_addr[3] = 0;
+			}
+#endif
+#endif
+			if (getnameinfo(p->addr, sysdep_sa_len(p->addr),
+					addr1, sizeof(addr1),
+					NULL, 0,
+					NI_NUMERICHOST | niflags))
+			strlcpy(addr1, "(invalid)", sizeof(addr1));
+			plog(LLV_DEBUG, LOCATION, NULL,
+				"my interface: %s (%s)\n",
+				addr1, ifr->ifr_name);
+			q = find_myaddr(old, p);
+			if (q)
+				p->sock = q->sock;
+			else
+				p->sock = -1;
+			p->next = lcconf->myaddrs;
+			lcconf->myaddrs = p;
+			break;
+		default:
+			break;
 		}
 	}
 
-	return TRUE;
+	clear_myaddr(&old);
+
+	racoon_free(iflist);
+#endif /*HAVE_GETIFADDRS*/
 }
 
+/*
+ * check the interface is suitable or not
+ */
 static int
-netlink_open_socket()
+suitable_ifaddr(ifname, ifaddr)
+	const char *ifname;
+	const struct sockaddr *ifaddr;
 {
-	int fd;
-
-	fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-	if (fd < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-			"socket(PF_NETLINK) failed: %s",
-			strerror(errno));
-		return -1;
-	}
-	close_on_exec(fd);
-	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "failed to put socket in non-blocking mode\n");
-
-	return fd;
-}
-
-static int
-kernel_open_socket()
-{
-	struct sockaddr_nl nl;
-	int fd;
-
-	if (netlink_fd < 0) {
-		netlink_fd = netlink_open_socket();
-		if (netlink_fd < 0)
-			return -1;
-	}
-
-	fd = netlink_open_socket();
-	if (fd < 0)
-		return fd;
-
-	/* We monitor IPv4 addresses using RTMGRP_IPV4_ROUTE group
-	 * the get the RTN_LOCAL routes which are automatically added
-	 * by kernel. This is because:
-	 *  - Linux kernel has a bug that calling bind() immediately
-	 *    after IPv4 RTM_NEWADDR event can fail
-	 *  - if IP is configured in multiple interfaces, we get
-	 *    RTM_DELADDR for each of them. RTN_LOCAL gets deleted only
-	 *    after the last IP address is deconfigured.
-	 * The latter reason is also why I chose to use route
-	 * notifications for IPv6. However, we do need to use RTM_NEWADDR
-	 * for the link-local IPv6 addresses to get the interface index
-	 * that is needed in bind().
-	 */
-	memset(&nl, 0, sizeof(nl));
-	nl.nl_family = AF_NETLINK;
-	nl.nl_groups = RTMGRP_IPV4_ROUTE 
-#ifdef INET6
-			| RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE
+#ifdef ENABLE_HYBRID
+	/* Exclude any address we got through ISAKMP mode config */
+	if (exclude_cfg_addr(ifaddr) == 0)
+		return 0;
 #endif
-			;
-	if (bind(fd, (struct sockaddr*) &nl, sizeof(nl)) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "bind(PF_NETLINK) failed: %s\n",
-		     strerror(errno));
-		close(fd);
-		return -1;
+	switch(ifaddr->sa_family) {
+	case AF_INET:
+		return 1;
+#ifdef INET6
+	case AF_INET6:
+		return suitable_ifaddr6(ifname, ifaddr);
+#endif
+	default:
+		return 0;
 	}
-	return fd;
+	/*NOTREACHED*/
 }
 
-static void
-kernel_sync()
-{
-	int fd = lcconf->rtsock;
-
-	/* refresh addresses */
-	if (!netlink_enumerate(fd, PF_UNSPEC, RTM_GETROUTE)) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unable to enumerate addresses: %s\n",
-		     strerror(errno));
-	}
-	while (kernel_receive(NULL, fd) == TRUE);
-
 #ifdef INET6
-	if (!netlink_enumerate(fd, PF_INET6, RTM_GETADDR)) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unable to enumerate addresses: %s\n",
-		     strerror(errno));
-	}
-	while (kernel_receive(NULL, fd) == TRUE);
-#endif
-}
-
-#elif defined(USE_ROUTE)
-
-#define ROUNDUP(a) \
-  ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-#define SAROUNDUP(X)   ROUNDUP(((struct sockaddr *)(X))->sa_len)
-
-static size_t
-parse_address(start, end, dest)
-	caddr_t start;
-	caddr_t end;
-	struct sockaddr_storage *dest;
+static int
+suitable_ifaddr6(ifname, ifaddr)
+	const char *ifname;
+	const struct sockaddr *ifaddr;
 {
-	int len;
+#ifndef __linux__
+	struct in6_ifreq ifr6;
+	int s;
+#endif
 
-	if (start >= end)
+	if (ifaddr->sa_family != AF_INET6)
 		return 0;
 
-	len = SAROUNDUP(start);
-	if (start + len > end)
-		return end - start;
+#ifndef __linux__
+	s = socket(PF_INET6, SOCK_DGRAM, 0);
+	if (s == -1) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"socket(SOCK_DGRAM) failed:%s\n", strerror(errno));
+		return 0;
+	}
 
-	if (dest != NULL && len <= sizeof(struct sockaddr_storage))
-		memcpy(dest, start, len);
+	memset(&ifr6, 0, sizeof(ifr6));
+	strncpy(ifr6.ifr_name, ifname, strlen(ifname));
 
-	return len;
+	ifr6.ifr_addr = *(const struct sockaddr_in6 *)ifaddr;
+
+	if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"ioctl(SIOCGIFAFLAG_IN6) failed:%s\n", strerror(errno));
+		close(s);
+		return 0;
+	}
+
+	close(s);
+
+	if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED
+	 || ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED
+	 || ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST)
+		return 0;
+#endif
+
+	/* suitable */
+	return 1;
 }
+#endif
 
-static void
-parse_addresses(start, end, flags, addr)
-	caddr_t start;
-	caddr_t end;
-	int flags;
-	struct sockaddr_storage *addr;
+int
+update_myaddrs()
 {
-	memset(addr, 0, sizeof(*addr));
-	if (flags & RTA_DST)
-		start += parse_address(start, end, NULL);
-	if (flags & RTA_GATEWAY)
-		start += parse_address(start, end, NULL);
-	if (flags & RTA_NETMASK)
-		start += parse_address(start, end, NULL);
-	if (flags & RTA_GENMASK)
-		start += parse_address(start, end, NULL);
-	if (flags & RTA_IFP)
-		start += parse_address(start, end, NULL);
-	if (flags & RTA_IFA)
-		start += parse_address(start, end, addr);
-	if (flags & RTA_AUTHOR)
-		start += parse_address(start, end, NULL);
-	if (flags & RTA_BRD)
-		start += parse_address(start, end, NULL);
-}
+#ifdef __linux__
+	char msg[BUFSIZ];
+	int len;
+	struct nlmsghdr *h = (void*)msg;
+	len = read(lcconf->rtsock, msg, sizeof(msg));
+	if (len < 0)
+		return errno == ENOBUFS;
+	if (len < sizeof(*h))
+		return 0;
+	if (h->nlmsg_pid) /* not from kernel! */
+		return 0;
+	if (h->nlmsg_type == RTM_NEWLINK)
+		return 0;
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"netlink signals update interface address list\n");
+	return 1;
+#else
+	char msg[BUFSIZ];
+	int len;
+	struct rt_msghdr *rtm;
 
-static void
-kernel_handle_message(msg)
-	caddr_t msg;
-{
-	struct rt_msghdr *rtm = (struct rt_msghdr *) msg;
-	struct ifa_msghdr *ifa = (struct ifa_msghdr *) msg;
-	struct sockaddr_storage addr;
-
+	len = read(lcconf->rtsock, msg, sizeof(msg));
+	if (len < 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"read(PF_ROUTE) failed: %s\n",
+			strerror(errno));
+		return 0;
+	}
+	rtm = (struct rt_msghdr *)msg;
+	if (len < rtm->rtm_msglen) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"read(PF_ROUTE) short read\n");
+		return 0;
+	}
+	if (rtm->rtm_version != RTM_VERSION) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"routing socket version mismatch\n");
+		close(lcconf->rtsock);
+		lcconf->rtsock = -1;
+		return 0;
+	}
 	switch (rtm->rtm_type) {
 	case RTM_NEWADDR:
-		parse_addresses(ifa + 1, msg + ifa->ifam_msglen,
-				ifa->ifam_addrs, &addr);
-		myaddr_open_all_configured((struct sockaddr *) &addr);
-		break;
 	case RTM_DELADDR:
-		parse_addresses(ifa + 1, msg + ifa->ifam_msglen,
-				ifa->ifam_addrs, &addr);
-		myaddr_close_all_open((struct sockaddr *) &addr);
-		break;
-	case RTM_ADD:
 	case RTM_DELETE:
-	case RTM_CHANGE:
-	case RTM_MISS:
 	case RTM_IFINFO:
-#ifdef RTM_OIFINFO
-	case RTM_OIFINFO:
-#endif
-#ifdef RTM_NEWMADDR
-	case RTM_NEWMADDR:
-	case RTM_DELMADDR:
-#endif
-#ifdef RTM_IFANNOUNCE
-	case RTM_IFANNOUNCE:
-#endif
 		break;
+	case RTM_MISS:
+		/* ignore this message silently */
+		return 0;
 	default:
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "unrecognized route message with rtm_type: %d",
-		     rtm->rtm_type);
-		break;
+		plog(LLV_DEBUG, LOCATION, NULL,
+			"msg %d not interesting\n", rtm->rtm_type);
+		return 0;
 	}
+	/* XXX more filters here? */
+
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"caught rtm:%d, need update interface address list\n",
+		rtm->rtm_type);
+	return 1;
+#endif /* __linux__ */
 }
 
-static int
-kernel_receive(ctx, fd)
-	void *ctx;
-	int fd;
+/*
+ * initialize default port for ISAKMP to send, if no "listen"
+ * directive is specified in config file.
+ *
+ * DO NOT listen to wildcard addresses.  if you receive packets to
+ * wildcard address, you'll be in trouble (DoS attack possible by
+ * broadcast storm).
+ */
+int
+autoconf_myaddrsport()
 {
-	char buf[16*1024];
-	struct rt_msghdr *rtm = (struct rt_msghdr *) buf;
-	int len;
+	struct myaddrs *p;
+	int n;
 
-	len = read(fd, &buf, sizeof(buf));
-	if (len <= 0) {
-		if (len < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
-			plog(LLV_WARNING, LOCATION, NULL,
-			     "routing socket error: %s", strerror(errno));
-		return FALSE;
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"configuring default isakmp port.\n");
+
+#ifdef ENABLE_NATT
+	if (natt_enabled_in_rmconf ()) {
+		plog(LLV_NOTIFY, LOCATION, NULL, "NAT-T is enabled, autoconfiguring ports\n");
+		for (p = lcconf->myaddrs; p; p = p->next) {
+			struct myaddrs *new;
+			if (! p->udp_encap) {
+				new = dupmyaddr(p);
+				new->udp_encap = 1;
+			}
+		}
 	}
+#endif
 
-	if (rtm->rtm_msglen != len) {
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "kernel_receive: rtm->rtm_msglen %d, len %d, type %d\n",
-		     rtm->rtm_msglen, len, rtm->rtm_type);
-		return FALSE;
+	for (p = lcconf->myaddrs, n = 0; p; p = p->next, n++) {
+		set_port (p->addr, p->udp_encap ? lcconf->port_isakmp_natt : lcconf->port_isakmp);
 	}
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"%d addrs are configured successfully\n", n);
 
-	kernel_handle_message(buf);
-	return TRUE;
+	return 0;
 }
 
-static int
-kernel_open_socket()
+/*
+ * get a port number to which racoon binded.
+ */
+u_short
+getmyaddrsport(local)
+	struct sockaddr *local;
 {
-	int fd;
+	struct myaddrs *p, *bestmatch = NULL;
+	u_short bestmatch_port = PORT_ISAKMP;
 
-	fd = socket(PF_ROUTE, SOCK_RAW, 0);
-	if (fd < 0) {
+	/* get a relative port */
+	for (p = lcconf->myaddrs; p; p = p->next) {
+		if (!p->addr)
+			continue;
+		if (cmpsaddrwop(local, p->addr))
+			continue;
+
+		/* use first matching address regardless of port */
+		if (!bestmatch) {
+			bestmatch = p;
+			continue;
+		}
+
+		/* matching address with port PORT_ISAKMP */
+		if (extract_port(p->addr) == PORT_ISAKMP) {
+			bestmatch = p;
+			bestmatch_port = PORT_ISAKMP;
+		}
+	}
+
+	return bestmatch_port;
+}
+
+struct myaddrs *
+newmyaddr()
+{
+	struct myaddrs *new;
+
+	new = racoon_calloc(1, sizeof(*new));
+	if (new == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to allocate buffer for myaddrs.\n");
+		return NULL;
+	}
+
+	new->next = NULL;
+	new->addr = NULL;
+
+	return new;
+}
+
+struct myaddrs *
+dupmyaddr(struct myaddrs *old)
+{
+	struct myaddrs *new;
+
+	new = racoon_calloc(1, sizeof(*new));
+	if (new == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to allocate buffer for myaddrs.\n");
+		return NULL;
+	}
+
+	/* Copy the whole structure and set the differences.  */
+	memcpy (new, old, sizeof (*new));
+	new->addr = dupsaddr (old->addr);
+	if (new->addr == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to allocate buffer for myaddrs.\n");
+		racoon_free(new);
+		return NULL;
+	}
+	new->next = old->next;
+	old->next = new;
+
+	return new;
+}
+
+void
+insmyaddr(new, head)
+	struct myaddrs *new;
+	struct myaddrs **head;
+{
+	new->next = *head;
+	*head = new;
+}
+
+void
+delmyaddr(myaddr)
+	struct myaddrs *myaddr;
+{
+	if (myaddr->addr)
+		racoon_free(myaddr->addr);
+	racoon_free(myaddr);
+}
+
+int
+initmyaddr()
+{
+	/* initialize routing socket */
+	lcconf->rtsock = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);
+	if (lcconf->rtsock < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"socket(PF_ROUTE) failed: %s",
 			strerror(errno));
 		return -1;
 	}
-	close_on_exec(fd);
-	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "failed to put socket in non-blocking mode\n");
 
-	return fd;
-}
+#ifdef __linux__
+   {
+	struct sockaddr_nl nl;
+	u_int addr_len;
 
-static void
-kernel_sync()
-{
-	caddr_t ref, buf, end;
-	size_t bufsiz;
-	struct if_msghdr *ifm;
-	struct interface *ifp;
+	memset(&nl, 0, sizeof(nl));
+	nl.nl_family = AF_NETLINK;
+	nl.nl_groups = RTMGRP_IPV4_IFADDR|RTMGRP_LINK|RTMGRP_IPV6_IFADDR;
 
-#define MIBSIZ 6
-	int mib[MIBSIZ] = {
-		CTL_NET,
-		PF_ROUTE,
-		0,
-		0, /*  AF_INET & AF_INET6 */
-		NET_RT_IFLIST,
-		0
-	};
-
-	if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) {
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "sysctl() error: %s", strerror(errno));
-		return;
+	if (bind(lcconf->rtsock, (struct sockaddr*)&nl, sizeof(nl)) < 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		     "bind(PF_NETLINK) failed: %s\n",
+		     strerror(errno));
+		return -1;
 	}
-
-	ref = buf = racoon_malloc(bufsiz);
-
-	if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) >= 0) {
-		/* Parse both interfaces and addresses. */
-		for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) {
-			ifm = (struct if_msghdr *) buf;
-			kernel_handle_message(buf);
-		}
-	} else {
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "sysctl() error: %s", strerror(errno));
+	addr_len = sizeof(nl);
+	if (getsockname(lcconf->rtsock, (struct sockaddr*)&nl, &addr_len) < 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		     "getsockname(PF_NETLINK) failed: %s\n",
+		     strerror(errno));
+		return -1;
 	}
-
-	racoon_free(ref);
-}
-
-#else
-
-#error No supported interface to monitor local addresses.
-
+   }
 #endif
+
+	if (lcconf->myaddrs == NULL && lcconf->autograbaddr == 1) {
+		grab_myaddrs();
+
+		if (autoconf_myaddrsport() < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+/* select the socket to be sent */
+/* should implement other method. */
+int
+getsockmyaddr(my)
+	struct sockaddr *my;
+{
+	struct myaddrs *p, *lastresort = NULL;
+#if defined(INET6) && defined(__linux__)
+	struct myaddrs *match_wo_scope_id = NULL;
+	int check_wo_scope_id = (my->sa_family == AF_INET6) && 
+		IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)my)->sin6_addr);
+#endif
+
+	for (p = lcconf->myaddrs; p; p = p->next) {
+		if (p->addr == NULL)
+			continue;
+		if (my->sa_family == p->addr->sa_family) {
+			lastresort = p;
+		} else continue;
+		if (sysdep_sa_len(my) == sysdep_sa_len(p->addr)
+		 && memcmp(my, p->addr, sysdep_sa_len(my)) == 0) {
+			break;
+		}
+#if defined(INET6) && defined(__linux__)
+		if (check_wo_scope_id && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)p->addr)->sin6_addr) &&
+			/* XXX: this depends on sin6_scope_id to be last
+			 * item in struct sockaddr_in6 */
+			memcmp(my, p->addr, 
+				sysdep_sa_len(my) - sizeof(uint32_t)) == 0) {
+			match_wo_scope_id = p;
+		}
+#endif
+	}
+#if defined(INET6) && defined(__linux__)
+	if (!p)
+		p = match_wo_scope_id;
+#endif
+	if (!p)
+		p = lastresort;
+	if (!p) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"no socket matches address family %d\n",
+			my->sa_family);
+		return -1;
+	}
+
+	return p->sock;
+}
diff --git a/src/racoon/grabmyaddr.h b/src/racoon/grabmyaddr.h
index a105d8f..ac74b46 100644
--- a/src/racoon/grabmyaddr.h
+++ b/src/racoon/grabmyaddr.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: grabmyaddr.h,v 1.6 2009/04/21 18:38:32 tteras Exp $	*/
+/*	$NetBSD: grabmyaddr.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: grabmyaddr.h,v 1.5 2004/06/11 16:00:16 ludvigm Exp */
 
@@ -34,15 +34,23 @@
 #ifndef _GRABMYADDR_H
 #define _GRABMYADDR_H
 
-extern void myaddr_init_lists __P((void));
-extern int myaddr_init __P((void));
-extern void myaddr_close __P((void));
+struct myaddrs {
+	struct myaddrs *next;
+	struct sockaddr *addr;
+	int sock;
+	int udp_encap;
+};
 
-extern void myaddr_flush __P((void));
-extern int myaddr_listen __P((struct sockaddr *, int));
-extern void myaddr_sync __P((void));
-
-extern int myaddr_getfd __P((struct sockaddr *));
-extern int myaddr_getsport __P((struct sockaddr *));
+extern void clear_myaddr __P((struct myaddrs **));
+extern void grab_myaddrs __P((void));
+extern int update_myaddrs __P((void));
+extern int autoconf_myaddrsport __P((void));
+extern u_short getmyaddrsport __P((struct sockaddr *));
+extern struct myaddrs *newmyaddr __P((void));
+extern struct myaddrs *dupmyaddr __P((struct myaddrs *));
+extern void insmyaddr __P((struct myaddrs *, struct myaddrs **));
+extern void delmyaddr __P((struct myaddrs *));
+extern int initmyaddr __P((void));
+extern int getsockmyaddr __P((struct sockaddr *));
 
 #endif /* _GRABMYADDR_H */
diff --git a/src/racoon/handler.c b/src/racoon/handler.c
index a795ee6..b643256 100644
--- a/src/racoon/handler.c
+++ b/src/racoon/handler.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: handler.c,v 1.39 2011/03/14 17:18:12 tteras Exp $	*/
+/*	$NetBSD: handler.c,v 1.9.6.8 2009/04/20 13:25:27 tteras Exp $	*/
 
 /* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -64,7 +64,7 @@
 #include "evt.h"
 #include "isakmp.h"
 #ifdef ENABLE_HYBRID
-#include "isakmp_xauth.h"
+#include "isakmp_xauth.h"  
 #include "isakmp_cfg.h"
 #endif
 #include "isakmp_inf.h"
@@ -85,10 +85,10 @@
 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
-static struct sched sc_sweep = SCHED_INITIALIZER();
 
 static void del_recvdpkt __P((struct recvdpkt *));
 static void rem_recvdpkt __P((struct recvdpkt *));
+static void sweep_recvdpkt __P((void *));
 
 /*
  * functions about management of the isakmp status table
@@ -100,41 +100,6 @@
 
 extern caddr_t val2str(const char *, size_t);
 
-/*
- * Enumerate the Phase 1 tree.
- * If enum_func() internally return a non-zero value,  this specific
- * error value is returned. 0 is returned if everything went right.
- *
- * Note that it is ok for enum_func() to call insph1(). Those inserted
- * Phase 1 will not interfere with current enumeration process.
- */
-int
-enumph1(sel, enum_func, enum_arg)
-	struct ph1selector *sel;
-	int (* enum_func)(struct ph1handle *iph1, void *arg);
-	void *enum_arg;
-{
-	struct ph1handle *p;
-	int ret;
-
-	LIST_FOREACH(p, &ph1tree, chain) {
-		if (sel != NULL) {
-			if (sel->local != NULL &&
-			    cmpsaddr(sel->local, p->local) > CMPSADDR_WILDPORT_MATCH)
-				continue;
-
-			if (sel->remote != NULL &&
-			    cmpsaddr(sel->remote, p->remote) > CMPSADDR_WILDPORT_MATCH)
-				continue;
-		}
-
-		if ((ret = enum_func(p, enum_arg)) != 0)
-			return ret;
-	}
-
-	return 0;
-}
-
 struct ph1handle *
 getph1byindex(index)
 	isakmp_index *index;
@@ -142,7 +107,7 @@
 	struct ph1handle *p;
 
 	LIST_FOREACH(p, &ph1tree, chain) {
-		if (p->status >= PHASE1ST_EXPIRED)
+		if (p->status == PHASE1ST_EXPIRED)
 			continue;
 		if (memcmp(&p->index, index, sizeof(*index)) == 0)
 			return p;
@@ -162,7 +127,7 @@
 	struct ph1handle *p;
 
 	LIST_FOREACH(p, &ph1tree, chain) {
-		if (p->status >= PHASE1ST_EXPIRED)
+		if (p->status == PHASE1ST_EXPIRED)
 			continue;
 		if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
 			return p;
@@ -177,57 +142,31 @@
  * with phase 2's destinaion.
  */
 struct ph1handle *
-getph1(ph1hint, local, remote, flags)
-	struct ph1handle *ph1hint;
+getph1byaddr(local, remote, established)
 	struct sockaddr *local, *remote;
-	int flags;
+	int established;
 {
 	struct ph1handle *p;
 
-	plog(LLV_DEBUG2, LOCATION, NULL, "getph1: start\n");
+	plog(LLV_DEBUG2, LOCATION, NULL, "getph1byaddr: start\n");
 	plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local));
 	plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote));
 
 	LIST_FOREACH(p, &ph1tree, chain) {
-		if (p->status >= PHASE1ST_DYING)
+		if (p->status == PHASE1ST_EXPIRED)
 			continue;
-
 		plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local));
 		plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote));
 
-		if ((flags & GETPH1_F_ESTABLISHED) &&
-		    (p->status != PHASE1ST_ESTABLISHED)) {
-			plog(LLV_DEBUG2, LOCATION, NULL,
-			     "status %d, skipping\n", p->status);
+		if(established && p->status != PHASE1ST_ESTABLISHED){
+			plog(LLV_DEBUG2, LOCATION, NULL, "status %d, skipping\n", p->status);
 			continue;
 		}
-
-		if (local != NULL && cmpsaddr(local, p->local) == CMPSADDR_MISMATCH)
-			continue;
-
-		if (remote != NULL && cmpsaddr(remote, p->remote) == CMPSADDR_MISMATCH)
-			continue;
-
-		if (ph1hint != NULL) {
-			if (ph1hint->id && ph1hint->id->l && p->id && p->id->l &&
-			    (ph1hint->id->l != p->id->l ||
-			     memcmp(ph1hint->id->v, p->id->v, p->id->l) != 0)) {
-				plog(LLV_DEBUG2, LOCATION, NULL,
-				     "local identity does match hint\n");
-				continue;
-			}
-			if (ph1hint->id_p && ph1hint->id_p->l &&
-			    p->id_p && p->id_p->l &&
-			    (ph1hint->id_p->l != p->id_p->l ||
-			     memcmp(ph1hint->id_p->v, p->id_p->v, p->id_p->l) != 0)) {
-				plog(LLV_DEBUG2, LOCATION, NULL,
-				     "remote identity does match hint\n");
-				continue;
-			}
+		if (CMPSADDR(local, p->local) == 0
+			&& CMPSADDR(remote, p->remote) == 0){
+			plog(LLV_DEBUG2, LOCATION, NULL, "matched\n");
+			return p;
 		}
-
-		plog(LLV_DEBUG2, LOCATION, NULL, "matched\n");
-		return p;
 	}
 
 	plog(LLV_DEBUG2, LOCATION, NULL, "no match\n");
@@ -235,77 +174,43 @@
 	return NULL;
 }
 
-int
-resolveph1rmconf(iph1)
-	struct ph1handle *iph1;
-{
-	struct remoteconf *rmconf;
-
-	/* INITIATOR is always expected to know the exact rmconf. */
-	if (iph1->side == INITIATOR)
-		return 0;
-
-	rmconf = getrmconf_by_ph1(iph1);
-	if (rmconf == NULL)
-		return -1;
-	if (rmconf == RMCONF_ERR_MULTIPLE)
-		return 1;
-
-	if (iph1->rmconf != NULL) {
-		if (rmconf != iph1->rmconf) {
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "unexpected rmconf switch; killing ph1\n");
-			return -1;
-		}
-	} else {
-		iph1->rmconf = rmconf;
-	}
-
-	return 0;
-}
-
-
-/*
- * move phase2s from old_iph1 to new_iph1
- */
-void
-migrate_ph12(old_iph1, new_iph1)
-	struct ph1handle *old_iph1, *new_iph1;
-{
-	struct ph2handle *p, *next;
-
-	/* Relocate phase2s to better phase1s or request a new phase1. */
-	for (p = LIST_FIRST(&old_iph1->ph2tree); p; p = next) {
-		next = LIST_NEXT(p, ph1bind);
-
-		if (p->status != PHASE2ST_ESTABLISHED)
-			continue;
-
-		unbindph12(p);
-		bindph12(new_iph1, p);
-	}
-}
-
-/*
- * the iph1 is new, migrate all phase2s that belong to a dying or dead ph1
- */
-void migrate_dying_ph12(iph1)
-	struct ph1handle *iph1;
+struct ph1handle *
+getph1byaddrwop(local, remote)
+	struct sockaddr *local, *remote;
 {
 	struct ph1handle *p;
 
 	LIST_FOREACH(p, &ph1tree, chain) {
-		if (p == iph1)
+		if (p->status == PHASE1ST_EXPIRED)
 			continue;
-		if (p->status < PHASE1ST_DYING)
-			continue;
-
-		if (cmpsaddr(iph1->local, p->local) == CMPSADDR_MATCH
-		 && cmpsaddr(iph1->remote, p->remote) == CMPSADDR_MATCH)
-			migrate_ph12(p, iph1);
+		if (cmpsaddrwop(local, p->local) == 0
+		 && cmpsaddrwop(remote, p->remote) == 0)
+			return p;
 	}
+
+	return NULL;
 }
 
+/*
+ * search for isakmpsa handler by remote address.
+ * don't use port number to search because this function search
+ * with phase 2's destinaion.
+ */
+struct ph1handle *
+getph1bydstaddrwop(remote)
+	struct sockaddr *remote;
+{
+	struct ph1handle *p;
+
+	LIST_FOREACH(p, &ph1tree, chain) {
+		if (p->status == PHASE1ST_EXPIRED)
+			continue;
+		if (cmpsaddrwop(remote, p->remote) == 0)
+			return p;
+	}
+
+	return NULL;
+}
 
 /*
  * dump isakmp-sa
@@ -363,10 +268,11 @@
 
 #ifdef ENABLE_DPD
 	iph1->dpd_support = 0;
+	iph1->dpd_lastack = 0;
 	iph1->dpd_seq = 0;
 	iph1->dpd_fails = 0;
+	iph1->dpd_r_u = NULL;
 #endif
-	evt_list_init(&iph1->evt_listeners);
 
 	return iph1;
 }
@@ -383,7 +289,8 @@
 
 	/* SA down shell script hook */
 	script_hook(iph1, SCRIPT_PHASE1_DOWN);
-	evt_list_cleanup(&iph1->evt_listeners);
+
+	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
 
 #ifdef ENABLE_NATT
 	if (iph1->natt_flags & NAT_KA_QUEUED)
@@ -401,10 +308,8 @@
 #endif
 
 #ifdef ENABLE_DPD
-	sched_cancel(&iph1->dpd_r_u);
+	SCHED_KILL(iph1->dpd_r_u);
 #endif
-	sched_cancel(&iph1->sce);
-	sched_cancel(&iph1->scr);
 
 	if (iph1->remote) {
 		racoon_free(iph1->remote);
@@ -420,7 +325,13 @@
 	}
 
 	VPTRINIT(iph1->authstr);
+
+	sched_scrub_param(iph1);
+	iph1->sce = NULL;
+	iph1->scr = NULL;
+
 	VPTRINIT(iph1->sendbuf);
+
 	VPTRINIT(iph1->dhpriv);
 	VPTRINIT(iph1->dhpub);
 	VPTRINIT(iph1->dhpub_p);
@@ -435,10 +346,14 @@
 	VPTRINIT(iph1->hash);
 	VPTRINIT(iph1->sig);
 	VPTRINIT(iph1->sig_p);
-	VPTRINIT(iph1->cert);
-	VPTRINIT(iph1->cert_p);
-	VPTRINIT(iph1->crl_p);
-	VPTRINIT(iph1->cr_p);
+	oakley_delcert(iph1->cert);
+	iph1->cert = NULL;
+	oakley_delcert(iph1->cert_p);
+	iph1->cert_p = NULL;
+	oakley_delcert(iph1->crl_p);
+	iph1->crl_p = NULL;
+	oakley_delcert(iph1->cr_p);
+	iph1->cr_p = NULL;
 	VPTRINIT(iph1->id);
 	VPTRINIT(iph1->id_p);
 
@@ -500,7 +415,7 @@
 		next = LIST_NEXT(p, chain);
 
 		/* send delete information */
-		if (p->status >= PHASE1ST_ESTABLISHED)
+		if (p->status == PHASE1ST_ESTABLISHED) 
 			isakmp_info_send_d1(p);
 
 		remph1(p);
@@ -514,52 +429,26 @@
 	LIST_INIT(&ph1tree);
 }
 
-int
-ph1_rekey_enabled(iph1)
-	struct ph1handle *iph1;
-{
-	if (iph1->rmconf == NULL)
-		return 0;
-	if (iph1->rmconf->rekey == REKEY_FORCE)
-		return 1;
-#ifdef ENABLE_DPD
-	if (iph1->rmconf->rekey == REKEY_ON && iph1->dpd_support &&
-	    iph1->rmconf->dpd_interval)
-		return 1;
-#endif
-	return 0;
-}
-
 /* %%% management phase 2 handler */
-
-int
-enumph2(sel, enum_func, enum_arg)
-	struct ph2selector *sel;
-	int (*enum_func)(struct ph2handle *ph2, void *arg);
-	void *enum_arg;
+/*
+ * search ph2handle with policy id.
+ */
+struct ph2handle *
+getph2byspid(spid)
+      u_int32_t spid;
 {
 	struct ph2handle *p;
-	int ret;
 
 	LIST_FOREACH(p, &ph2tree, chain) {
-		if (sel != NULL) {
-			if (sel->spid != 0 && sel->spid != p->spid)
-				continue;
-
-			if (sel->src != NULL &&
-			    cmpsaddr(sel->src, p->src) != CMPSADDR_MATCH)
-				continue;
-
-			if (sel->dst != NULL &&
-			    cmpsaddr(sel->dst, p->dst) != CMPSADDR_MATCH)
-				continue;
-		}
-
-		if ((ret = enum_func(p, enum_arg)) != 0)
-			return ret;
+		/*
+		 * there are ph2handle independent on policy
+		 * such like informational exchange.
+		 */
+		if (p->spid == spid)
+			return p;
 	}
 
-	return 0;
+	return NULL;
 }
 
 /*
@@ -589,7 +478,7 @@
 {
 	struct ph2handle *p;
 
-	LIST_FOREACH(p, &iph1->ph2tree, ph1bind) {
+	LIST_FOREACH(p, &ph2tree, chain) {
 		if (p->msgid == msgid && p->ph1 == iph1)
 			return p;
 	}
@@ -597,15 +486,6 @@
 	return NULL;
 }
 
-/* Note that src and dst are not the selectors of the SP
- * but the source and destination addresses used for
- * for SA negotiation (best example is tunnel mode SA
- * where src and dst are the endpoints). There is at most
- * a unique match because racoon does not support bundles
- * which makes that there is at most a single established
- * SA for a given spid. One could say that src and dst
- * are in fact useless ...
- */
 struct ph2handle *
 getph2byid(src, dst, spid)
 	struct sockaddr *src, *dst;
@@ -615,8 +495,8 @@
 
 	LIST_FOREACH(p, &ph2tree, chain) {
 		if (spid == p->spid &&
-		    cmpsaddr(src, p->src) <= CMPSADDR_WILDPORT_MATCH &&
-		    cmpsaddr(dst, p->dst) <= CMPSADDR_WILDPORT_MATCH){
+		    CMPSADDR(src, p->src) == 0 &&
+		    CMPSADDR(dst, p->dst) == 0){
 			/* Sanity check to detect zombie handlers
 			 * XXX Sould be done "somewhere" more interesting,
 			 * because we have lots of getph2byxxxx(), but this one
@@ -624,7 +504,7 @@
 			 */
 			if(p->status < PHASE2ST_ESTABLISHED &&
 			   p->retry_counter == 0
-			   && p->sce.func == NULL && p->scr.func == NULL) {
+			   && p->sce == NULL && p->scr == NULL){
 				plog(LLV_DEBUG, LOCATION, NULL,
 					 "Zombie ph2 found, expiring it\n");
 				isakmp_ph2expire(p);
@@ -643,8 +523,8 @@
 	struct ph2handle *p;
 
 	LIST_FOREACH(p, &ph2tree, chain) {
-		if (cmpsaddr(src, p->src) <= CMPSADDR_WILDPORT_MATCH &&
-		    cmpsaddr(dst, p->dst) <= CMPSADDR_WILDPORT_MATCH)
+		if (cmpsaddrstrict(src, p->src) == 0 &&
+		    cmpsaddrstrict(dst, p->dst) == 0)
 			return p;
 	}
 
@@ -702,7 +582,6 @@
 		return NULL;
 
 	iph2->status = PHASE1ST_SPAWN;
-	evt_list_init(&iph2->evt_listeners);
 
 	return iph2;
 }
@@ -716,11 +595,9 @@
 initph2(iph2)
 	struct ph2handle *iph2;
 {
-	evt_list_cleanup(&iph2->evt_listeners);
-	unbindph12(iph2);
-
-	sched_cancel(&iph2->sce);
-	sched_cancel(&iph2->scr);
+	sched_scrub_param(iph2);
+	iph2->sce = NULL;
+	iph2->scr = NULL;
 
 	VPTRINIT(iph2->sendbuf);
 	VPTRINIT(iph2->msg1);
@@ -765,17 +642,6 @@
 		oakley_delivm(iph2->ivm);
 		iph2->ivm = NULL;
 	}
-
-#ifdef ENABLE_NATT
-	if (iph2->natoa_src) {
-		racoon_free(iph2->natoa_src);
-		iph2->natoa_src = NULL;
-	}
-	if (iph2->natoa_dst) {
-		racoon_free(iph2->natoa_dst);
-		iph2->natoa_dst = NULL;
-	}
-#endif
 }
 
 /*
@@ -795,24 +661,14 @@
 		racoon_free(iph2->dst);
 		iph2->dst = NULL;
 	}
-	if (iph2->sa_src) {
-		racoon_free(iph2->sa_src);
-		iph2->sa_src = NULL;
+	if (iph2->src_id) {
+	      racoon_free(iph2->src_id);
+	      iph2->src_id = NULL;
 	}
-	if (iph2->sa_dst) {
-		racoon_free(iph2->sa_dst);
-		iph2->sa_dst = NULL;
+	if (iph2->dst_id) {
+	      racoon_free(iph2->dst_id);
+	      iph2->dst_id = NULL;
 	}
-#ifdef ENABLE_NATT
-	if (iph2->natoa_src) {
-		racoon_free(iph2->natoa_src);
-		iph2->natoa_src = NULL;
-	}
-	if (iph2->natoa_dst) {
-		racoon_free(iph2->natoa_dst);
-		iph2->natoa_dst = NULL;
-	}
-#endif
 
 	if (iph2->proposal) {
 		flushsaprop(iph2->proposal);
@@ -838,7 +694,6 @@
 remph2(iph2)
 	struct ph2handle *iph2;
 {
-	unbindph12(iph2);
 	LIST_REMOVE(iph2, chain);
 }
 
@@ -870,6 +725,7 @@
 		}
 
 		delete_spd(p, 0);
+		unbindph12(p);
 		remph2(p);
 		delph2(p);
 	}
@@ -907,6 +763,7 @@
 		}
 		continue;
  zap_it:
+		unbindph12(iph2);
 		remph2(iph2);
 		delph2(iph2);
 	}
@@ -918,10 +775,7 @@
 	struct ph1handle *iph1;
 	struct ph2handle *iph2;
 {
-	unbindph12(iph2);
-
 	iph2->ph1 = iph1;
-	iph1->ph2cnt++;
 	LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
 }
 
@@ -930,9 +784,8 @@
 	struct ph2handle *iph2;
 {
 	if (iph2->ph1 != NULL) {
-		LIST_REMOVE(iph2, ph1bind);
-		iph2->ph1->ph2cnt--;
 		iph2->ph1 = NULL;
+		LIST_REMOVE(iph2, ph1bind);
 	}
 }
 
@@ -947,7 +800,7 @@
 	struct contacted *p;
 
 	LIST_FOREACH(p, &ctdtree, chain) {
-		if (cmpsaddr(remote, p->remote) <= CMPSADDR_WILDPORT_MATCH)
+		if (cmpsaddrstrict(remote, p->remote) == 0)
 			return p;
 	}
 
@@ -982,22 +835,6 @@
 }
 
 void
-remcontacted(remote)
-	struct sockaddr *remote;
-{
-	struct contacted *p;
-
-	LIST_FOREACH(p, &ctdtree, chain) {
-		if (cmpsaddr(remote, p->remote) <= CMPSADDR_WILDPORT_MATCH) {
-			LIST_REMOVE(p, chain);
-			racoon_free(p->remote);
-			racoon_free(p);
-			break;
-		}
-	}	
-}
-
-void
 initctdtree()
 {
 	LIST_INIT(&ctdtree);
@@ -1019,9 +856,12 @@
 {
 	vchar_t *hash;
 	struct recvdpkt *r;
-	struct timeval now, diff;
+	time_t t;
 	int len, s;
 
+	/* set current time */
+	t = time(NULL);
+
 	hash = eay_md5_one(rbuf);
 	if (!hash) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -1042,7 +882,7 @@
 	/*
 	 * the packet was processed before, but the remote address mismatches.
 	 */
-	if (cmpsaddr(remote, r->remote) != CMPSADDR_MATCH)
+	if (cmpsaddrstrict(remote, r->remote) != 0)
 		return 2;
 
 	/*
@@ -1051,9 +891,7 @@
 	 */
 
 	/* check the previous time to send */
-	sched_get_monotonic_time(&now);
-	timersub(&now, &r->time_send, &diff);
-	if (diff.tv_sec == 0) {
+	if (t - r->time_send < 1) {
 		plog(LLV_WARNING, LOCATION, NULL,
 			"the packet retransmitted in a short time from %s\n",
 			saddr2str(remote));
@@ -1061,7 +899,7 @@
 	}
 
 	/* select the socket to be sent */
-	s = myaddr_getfd(r->local);
+	s = getsockmyaddr(r->local);
 	if (s == -1)
 		return -1;
 
@@ -1082,7 +920,7 @@
 			"deleted the retransmission packet to %s.\n",
 			saddr2str(remote));
 	} else
-		r->time_send = now;
+		r->time_send = t;
 
 	return 1;
 }
@@ -1139,7 +977,8 @@
 	}
 
 	new->retry_counter = lcconf->retry_counter;
-	sched_get_monotonic_time(&new->time_send);
+	new->time_send = 0;
+	new->created = time(NULL);
 
 	LIST_INSERT_HEAD(&rcptree, new, chain);
 
@@ -1168,30 +1007,29 @@
 	LIST_REMOVE(r, chain);
 }
 
-static void
+void
 sweep_recvdpkt(dummy)
-	struct sched *dummy;
+	void *dummy;
 {
 	struct recvdpkt *r, *next;
-	struct timeval now, diff, sweep;
+	time_t t, lt;
 
-	sched_get_monotonic_time(&now);
+	/* set current time */
+	t = time(NULL);
 
-	/* calculate sweep time; delete entries older than this */
-	diff.tv_sec = lcconf->retry_counter * lcconf->retry_interval;
-	diff.tv_usec = 0;
-	timersub(&now, &diff, &sweep);
+	/* set the lifetime of the retransmission */
+	lt = lcconf->retry_counter * lcconf->retry_interval;
 
 	for (r = LIST_FIRST(&rcptree); r; r = next) {
 		next = LIST_NEXT(r, chain);
 
-		if (timercmp(&r->time_send, &sweep, <)) {
+		if (t - r->created > lt) {
 			rem_recvdpkt(r);
 			del_recvdpkt(r);
 		}
 	}
 
-	sched_schedule(&sc_sweep, diff.tv_sec, sweep_recvdpkt);
+	sched_new(lt, sweep_recvdpkt, NULL);
 }
 
 void
@@ -1201,11 +1039,11 @@
 
 	LIST_INIT(&rcptree);
 
-	sched_schedule(&sc_sweep, lt, sweep_recvdpkt);
+	sched_new(lt, sweep_recvdpkt, NULL);
 }
 
 #ifdef ENABLE_HYBRID
-/*
+/* 
  * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
  * This should be in isakmp_cfg.c but ph1tree being private, it must be there
  */
@@ -1232,7 +1070,7 @@
 
 
 
-/*
+/* 
  * Reload conf code
  */
 static int revalidate_ph2(struct ph2handle *iph2){
@@ -1242,19 +1080,19 @@
 	struct saprop *approval;
 	struct ph1handle *iph1;
 
-	/*
+	/* 
 	 * Get the new sainfo using values of the old one
 	 */
 	if (iph2->sainfo != NULL) {
-		iph2->sainfo = getsainfo(iph2->sainfo->idsrc,
+		iph2->sainfo = getsainfo(iph2->sainfo->idsrc, 
 					  iph2->sainfo->iddst, iph2->sainfo->id_i,
-					  NULL, iph2->sainfo->remoteid);
+					  iph2->sainfo->remoteid);
 	}
 	approval = iph2->approval;
 	sainfo = iph2->sainfo;
 
 	if (sainfo == NULL) {
-		/*
+		/* 
 		 * Sainfo has been removed
 		 */
 		plog(LLV_DEBUG, LOCATION, NULL,
@@ -1269,7 +1107,7 @@
 		plog(LLV_DEBUG, LOCATION, NULL,
 			 "No approval found !\n");
 		return 0;
-	}
+	}	
 
 	/*
 	 * Don't care about proposals, should we do something ?
@@ -1368,7 +1206,7 @@
 	}
 
 	found = 0;
-	for (alg = sainfo->algs[algclass_ipsec_enc];
+	for (alg = sainfo->algs[algclass_ipsec_enc]; 
 	    (found == 0 && alg != NULL); alg = alg->next) {
 		plog(LLV_DEBUG, LOCATION, NULL,
 			 "Reload: next ph2 enc alg...\n");
@@ -1401,7 +1239,7 @@
 			break;
 
 		default:
-			plog(LLV_ERROR, LOCATION, NULL,
+			plog(LLV_ERROR, LOCATION, NULL, 
 			    "unexpected check_level\n");
 			continue;
 			break;
@@ -1425,7 +1263,7 @@
 }
 
 
-static void
+static void 
 remove_ph2(struct ph2handle *iph2)
 {
 	u_int32_t spis[2];
@@ -1451,6 +1289,7 @@
 		purge_ipsec_spi(iph2->dst, iph2->approval->head->proto_id,
 						spis, 2);
 	}else{
+		unbindph12(iph2);
 		remph2(iph2);
 		delph2(iph2);
 	}
@@ -1465,41 +1304,197 @@
 	plog(LLV_DEBUG, LOCATION, NULL,
 		 "Removing PH1...\n");
 
-	if (iph1->status == PHASE1ST_ESTABLISHED ||
-	    iph1->status == PHASE1ST_DYING) {
+	if (iph1->status == PHASE1ST_ESTABLISHED){
 		for (iph2 = LIST_FIRST(&iph1->ph2tree); iph2; iph2 = iph2_next) {
-			iph2_next = LIST_NEXT(iph2, ph1bind);
+			iph2_next = LIST_NEXT(iph2, chain);
 			remove_ph2(iph2);
 		}
 		isakmp_info_send_d1(iph1);
 	}
 	iph1->status = PHASE1ST_EXPIRED;
-	/* directly call isakmp_ph1delete to avoid as possible a race
-	 * condition where we'll try to access iph1->rmconf after it has
-	 * freed
-	 */
-	isakmp_ph1delete(iph1);
+	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 }
 
 
-static int revalidate_ph1tree_rmconf(void)
-{
+static int revalidate_ph1tree_rmconf(void){
 	struct ph1handle *p, *next;
-	struct remoteconf *rmconf;
+	struct remoteconf *newrmconf;
 
 	for (p = LIST_FIRST(&ph1tree); p; p = next) {
 		next = LIST_NEXT(p, chain);
 
-		if (p->status >= PHASE1ST_EXPIRED)
-			continue;
-		if (p->rmconf == NULL)
+		if (p->status == PHASE1ST_EXPIRED)
 			continue;
 
-		rmconf = getrmconf_by_ph1(p);
-		if (rmconf == NULL || rmconf == RMCONF_ERR_MULTIPLE)
+		newrmconf=getrmconf(p->remote);
+		if(newrmconf == NULL){
+			p->rmconf = NULL;
 			remove_ph1(p);
-		else
-			p->rmconf = rmconf;
+		}else{
+			/* Do not free old rmconf, it is just a pointer to an entry in rmtree
+			 */
+			p->rmconf=newrmconf;
+			if(p->approval != NULL){
+				struct isakmpsa *tmpsa;
+
+				tmpsa=dupisakmpsa(p->approval);
+				if(tmpsa != NULL){
+					delisakmpsa(p->approval);
+					p->approval=tmpsa;
+					p->approval->rmconf=newrmconf;
+				}
+			}
+		}
+	}
+
+	return 1;
+}
+
+
+/* rmconf is already updated here
+ */
+static int revalidate_ph1(struct ph1handle *iph1){
+	struct isakmpsa *p, *approval;
+	struct etypes *e;
+
+	if(iph1 == NULL ||
+	   iph1->approval == NULL ||
+		iph1->rmconf == NULL)
+		return 0;
+
+	approval=iph1->approval;
+
+	for (e = iph1->rmconf->etypes; e != NULL; e = e->next){
+		if (iph1->etype == e->type)
+			break;
+	}
+
+	if (e == NULL){
+		plog(LLV_DEBUG, LOCATION, NULL,
+			 "Reload: Exchange type mismatch\n");
+		return 0;
+	}
+
+	if (iph1->etype == ISAKMP_ETYPE_AGG &&
+	   approval->dh_group != iph1->rmconf->dh_group){
+		plog(LLV_DEBUG, LOCATION, NULL,
+			 "Reload: DH mismatch\n");
+		return 0;
+	}
+
+	for (p=iph1->rmconf->proposal; p != NULL; p=p->next){
+		plog(LLV_DEBUG, LOCATION, NULL,
+			 "Reload: Trying next proposal...\n");
+
+		if(approval->authmethod != p->authmethod){
+			plog(LLV_DEBUG, LOCATION, NULL,
+				 "Reload: Authmethod mismatch\n");
+			continue;
+		}
+
+		if(approval->enctype != p->enctype){
+			plog(LLV_DEBUG, LOCATION, NULL,
+				 "Reload: enctype mismatch\n");
+			continue;
+		}
+
+		switch (iph1->rmconf->pcheck_level) {
+		case PROP_CHECK_OBEY:
+			plog(LLV_DEBUG, LOCATION, NULL,
+				 "Reload: OBEY pcheck level, ok...\n");
+			return 1;
+			break;
+
+		case PROP_CHECK_CLAIM:
+			/* FALLTHROUGH */
+		case PROP_CHECK_STRICT:
+			if (approval->encklen < p->encklen) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "Reload: encklen mismatch\n");
+				continue;
+			}
+
+			if (approval->lifetime > p->lifetime) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "Reload: lifetime mismatch\n");
+				continue;
+			}
+
+#if 0
+			/* Lifebyte is deprecated, just ignore it
+			 */
+			if (approval->lifebyte > p->lifebyte) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "Reload: lifebyte mismatch\n");
+				continue;
+			}
+#endif
+			break;
+
+		case PROP_CHECK_EXACT:
+			if (approval->encklen != p->encklen) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "Reload: encklen mismatch\n");
+				continue;
+			}
+
+			if (approval->lifetime != p->lifetime) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "Reload: lifetime mismatch\n");
+				continue;
+			}
+
+#if 0
+			/* Lifebyte is deprecated, just ignore it
+			 */
+			if (approval->lifebyte != p->lifebyte) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "Reload: lifebyte mismatch\n");
+				continue;
+			}
+#endif
+			break;
+
+		default:
+			plog(LLV_ERROR, LOCATION, NULL, 
+			    "unexpected check_level\n");
+			continue;
+			break;
+		}
+
+		if (approval->hashtype != p->hashtype) {
+			plog(LLV_DEBUG, LOCATION, NULL,
+				 "Reload: hashtype mismatch\n");
+			continue;
+		}
+
+		if (iph1->etype != ISAKMP_ETYPE_AGG &&
+		    approval->dh_group != p->dh_group) {
+			plog(LLV_DEBUG, LOCATION, NULL,
+				 "Reload: dhgroup mismatch\n");
+			continue;
+		}
+
+		plog(LLV_DEBUG, LOCATION, NULL, "Reload: Conf ok\n");
+		return 1;
+	}
+
+	plog(LLV_DEBUG, LOCATION, NULL, "Reload: No valid conf found\n");
+	return 0;
+}
+
+
+static int revalidate_ph1tree(void){
+	struct ph1handle *p, *next;
+
+	for (p = LIST_FIRST(&ph1tree); p; p = next) {
+		next = LIST_NEXT(p, chain);
+
+		if (p->status == PHASE1ST_EXPIRED)
+			continue;
+
+		if(!revalidate_ph1(p))
+			remove_ph1(p);
 	}
 
 	return 1;
@@ -1524,12 +1519,14 @@
 	return 1;
 }
 
-int
+int 
 revalidate_ph12(void)
 {
 
 	revalidate_ph1tree_rmconf();
+
 	revalidate_ph2tree();
+	revalidate_ph1tree();
 
 	return 1;
 }
@@ -1562,10 +1559,7 @@
 		if (p->mode_cfg == NULL)
 			continue;
 		if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) {
-			if (p->status >= PHASE1ST_EXPIRED)
-				continue;
-
-			if (p->status >= PHASE1ST_ESTABLISHED)
+			if (p->status == PHASE1ST_ESTABLISHED)
 				isakmp_info_send_d1(p);
 			purge_remote(p);
 			found++;
diff --git a/src/racoon/handler.h b/src/racoon/handler.h
index 45d596e..a52dc6c 100644
--- a/src/racoon/handler.h
+++ b/src/racoon/handler.h
@@ -1,11 +1,11 @@
-/*	$NetBSD: handler.h,v 1.25 2010/11/17 10:40:41 tteras Exp $	*/
+/*	$NetBSD: handler.h,v 1.9.6.1 2008/01/11 14:12:01 vanhu Exp $	*/
 
 /* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -41,8 +41,6 @@
 
 #include "isakmp_var.h"
 #include "oakley.h"
-#include "schedule.h"
-#include "evt.h"
 
 /* Phase 1 handler */
 /*
@@ -95,9 +93,8 @@
 #define PHASE1ST_MSG3SENT		7
 #define PHASE1ST_MSG4RECEIVED		8
 #define PHASE1ST_ESTABLISHED		9
-#define PHASE1ST_DYING			10
-#define PHASE1ST_EXPIRED		11
-#define PHASE1ST_MAX			12
+#define PHASE1ST_EXPIRED		10
+#define PHASE1ST_MAX			11
 
 /* About address semantics in each case.
  *			initiator(addr=I)	responder(addr=R)
@@ -134,7 +131,6 @@
 	u_int8_t flags;			/* Flags */
 	u_int32_t msgid;		/* message id */
 
-	u_int32_t vendorid_mask;	/* bitmask of received supported vendor ids*/
 #ifdef ENABLE_NATT
 	struct ph1natt_options *natt_options;	/* Selected NAT-T IKE version */
 	u_int32_t natt_flags;		/* NAT-T related flags */
@@ -144,9 +140,9 @@
 	struct isakmp_frag_item *frag_chain;	/* Received fragments */
 #endif
 
-	struct sched sce;		/* schedule for expire */
+	struct sched *sce;		/* schedule for expire */
 
-	struct sched scr;		/* schedule for resend */
+	struct sched *scr;		/* schedule for resend */
 	int retry_counter;		/* for resend. */
 	vchar_t *sendbuf;		/* buffer for re-sending */
 
@@ -164,10 +160,10 @@
 	vchar_t *hash;			/* HASH minus general header */
 	vchar_t *sig;			/* SIG minus general header */
 	vchar_t *sig_p;			/* peer's SIG minus general header */
-	vchar_t *cert;			/* CERT minus general header */
-	vchar_t *cert_p;		/* peer's CERT minus general header */
-	vchar_t *crl_p;			/* peer's CRL minus general header */
-	vchar_t *cr_p;			/* peer's CR not including general */
+	cert_t *cert;			/* CERT minus general header */
+	cert_t *cert_p;			/* peer's CERT minus general header */
+	cert_t *crl_p;			/* peer's CRL minus general header */
+	cert_t *cr_p;			/* peer's CR not including general */
 	RSA *rsa;			/* my RSA key */
 	RSA *rsa_p;			/* peer's RSA key */
 	struct genlist *rsa_candidates;	/* possible candidates for peer's RSA key */
@@ -194,7 +190,6 @@
 	struct isakmp_pl_hash *pl_hash;	/* pointer to hash payload */
 
 	time_t created;			/* timestamp for establish */
-	int initial_contact_received;	/* set if initial contact received */
 #ifdef ENABLE_STATS
 	struct timeval start;
 	struct timeval end;
@@ -202,10 +197,10 @@
 
 #ifdef ENABLE_DPD
 	int		dpd_support;	/* Does remote supports DPD ? */
-	u_int32_t	dpd_last_ack;
-	u_int32_t	dpd_seq;		/* DPD seq number to receive */
+	time_t		dpd_lastack;	/* Last ack received */
+	u_int16_t	dpd_seq;		/* DPD seq number to receive */
 	u_int8_t	dpd_fails;		/* number of failures */
-	struct sched	dpd_r_u;
+	struct sched	*dpd_r_u;
 #endif
 
 	u_int32_t msgid2;		/* msgid counter for Phase 2 */
@@ -215,14 +210,8 @@
 	LIST_ENTRY(ph1handle) chain;
 #ifdef ENABLE_HYBRID
 	struct isakmp_cfg_state *mode_cfg;	/* ISAKMP mode config state */
-#endif
-	EVT_LISTENER_LIST(evt_listeners);
-};
+#endif       
 
-/* For limiting enumeration of ph1 tree */
-struct ph1selector {
-	struct sockaddr *local;
-	struct sockaddr *remote;
 };
 
 /* Phase 2 handler */
@@ -255,44 +244,23 @@
 #define PHASE2ST_MAX		11
 
 struct ph2handle {
-	/* source and destination addresses used for IKE exchange. Might
-	 * differ from source and destination of SA. On the initiator,
-	 * they are tweaked if a hint is available in the SPD (set by
-	 * MIGRATE for instance). Otherwise they are the source and
-	 * destination of SA for transport mode and the tunnel endpoints
-	 * for tunnel mode */
-	struct sockaddr *src;
-	struct sockaddr *dst;
+	struct sockaddr *src;		/* my address of SA. */
+	struct sockaddr *dst;		/* peer's address of SA. */
 
-	/* source and destination addresses of the SA in the case addresses
-	 * used for IKE exchanges (src and dst) do differ. On the initiator,
-	 * they are set (if needed) in pk_recvacquire(). On the responder,
-	 * they are _derived_ from the local and remote parameters of the
-	 * SP, if available. */
-	struct sockaddr *sa_src;
-	struct sockaddr *sa_dst;
-
-	/* Store our Phase 2 ID and the peer ID (ID minus general header).
-	 * On the initiator, they are set during ACQUIRE processing.
-	 * On the responder, they are set from the content of ID payload
-	 * in quick_r1recv(). Then, if they are of type address or
-	 * tunnel, they are compared to sainfo selectors.
-	 */
-	vchar_t *id;			/* ID minus gen header */
-	vchar_t *id_p;			/* peer's ID minus general header */
-
-#ifdef ENABLE_NATT
-	struct sockaddr *natoa_src;	/* peer's view of my address */
-	struct sockaddr *natoa_dst;	/* peer's view of his address */
-#endif
+		/*
+		 * copy ip address from ID payloads when ID type is ip address.
+		 * In other case, they must be null.
+		 */
+	struct sockaddr *src_id;
+	struct sockaddr *dst_id;
 
 	u_int32_t spid;			/* policy id by kernel */
 
 	int status;			/* ipsec sa status */
 	u_int8_t side;			/* INITIATOR or RESPONDER */
 
-	struct sched sce;		/* schedule for expire */
-	struct sched scr;		/* schedule for resend */
+	struct sched *sce;		/* schedule for expire */
+	struct sched *scr;		/* schedule for resend */
 	int retry_counter;		/* for resend. */
 	vchar_t *sendbuf;		/* buffer for re-sending */
 	vchar_t *msg1;			/* buffer for re-sending */
@@ -320,8 +288,6 @@
 	struct sainfo *sainfo;		/* place holder of sainfo */
 	struct saprop *proposal;	/* SA(s) proposal. */
 	struct saprop *approval;	/* SA(s) approved. */
-	u_int32_t lifetime_secs;	/* responder lifetime (seconds) */
-	u_int32_t lifetime_kb;		/* responder lifetime (kbytes) */
 	caddr_t spidx_gen;		/* policy from peer's proposal */
 
 	struct dhgroup *pfsgrp;		/* DH; prime number */
@@ -329,6 +295,8 @@
 	vchar_t *dhpub;			/* DH; public value */
 	vchar_t *dhpub_p;		/* DH; partner's public value */
 	vchar_t *dhgxy;			/* DH; shared secret */
+	vchar_t *id;			/* ID minus gen header */
+	vchar_t *id_p;			/* peer's ID minus general header */
 	vchar_t *nonce;			/* nonce value in phase 2 */
 	vchar_t *nonce_p;		/* partner's nonce value in phase 2 */
 
@@ -352,14 +320,6 @@
 
 	LIST_ENTRY(ph2handle) chain;
 	LIST_ENTRY(ph2handle) ph1bind;	/* chain to ph1handle */
-	EVT_LISTENER_LIST(evt_listeners);
-};
-
-/* For limiting enumeration of ph2 tree */
-struct ph2selector {
-	u_int32_t spid;
-	struct sockaddr *src;
-	struct sockaddr *dst;
 };
 
 /*
@@ -379,7 +339,10 @@
 	vchar_t *hash;			/* hash of the received packet */
 	vchar_t *sendbuf;		/* buffer for the response */
 	int retry_counter;		/* how many times to send */
-	struct timeval time_send;	/* timestamp of previous send */
+	time_t time_send;		/* timestamp to send a packet */
+	time_t created;			/* timestamp to create a queue */
+
+	struct sched *scr;		/* schedule for resend, may not used */
 
 	LIST_ENTRY(recvdpkt) chain;
 };
@@ -450,7 +413,7 @@
 	struct sockaddr_storage remote;
 	struct sockaddr_storage local;
 	u_int8_t version;
-	u_int8_t etype;
+	u_int8_t etype;	
 	time_t created;
 	int ph2cnt;
 };
@@ -462,42 +425,25 @@
 
 extern struct ph1handle *getph1byindex __P((isakmp_index *));
 extern struct ph1handle *getph1byindex0 __P((isakmp_index *));
-
-extern int enumph1 __P((struct ph1selector *ph1sel,
-			int (* enum_func)(struct ph1handle *iph1, void *arg),
-			void *enum_arg));
-
-#define GETPH1_F_ESTABLISHED		0x0001
-
-extern struct ph1handle *getph1 __P((struct ph1handle *ph1hint,
-				     struct sockaddr *local,
-				     struct sockaddr *remote,
-				     int flags));
-
-#define getph1byaddr(local, remote, est) \
-	getph1(NULL, local, remote, est ? GETPH1_F_ESTABLISHED : 0)
-#define getph1bydstaddr(remote) \
-	getph1(NULL, NULL, remote, 0)
-
+extern struct ph1handle *getph1byaddr __P((struct sockaddr *,
+										   struct sockaddr *, int));
+extern struct ph1handle *getph1byaddrwop __P((struct sockaddr *,
+	struct sockaddr *));
+extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *));
 #ifdef ENABLE_HYBRID
 struct ph1handle *getph1bylogin __P((char *));
 int purgeph1bylogin __P((char *));
 #endif
-extern void migrate_ph12 __P((struct ph1handle *old_iph1, struct ph1handle *new_iph1));
-extern void migrate_dying_ph12 __P((struct ph1handle *iph1));
 extern vchar_t *dumpph1 __P((void));
 extern struct ph1handle *newph1 __P((void));
 extern void delph1 __P((struct ph1handle *));
 extern int insph1 __P((struct ph1handle *));
 extern void remph1 __P((struct ph1handle *));
-extern int resolveph1rmconf __P((struct ph1handle *));
 extern void flushph1 __P((void));
 extern void initph1tree __P((void));
-extern int ph1_rekey_enabled __P((struct ph1handle *));
 
-extern int enumph2 __P((struct ph2selector *ph2sel,
-			int (* enum_func)(struct ph2handle *iph2, void *arg),
-			void *enum_arg));
+extern struct ph2handle *getph2byspidx __P((struct policyindex *));
+extern struct ph2handle *getph2byspid __P((u_int32_t));
 extern struct ph2handle *getph2byseq __P((u_int32_t));
 extern struct ph2handle *getph2bysaddr __P((struct sockaddr *,
 	struct sockaddr *));
@@ -520,7 +466,6 @@
 
 extern struct contacted *getcontacted __P((struct sockaddr *));
 extern int inscontacted __P((struct sockaddr *));
-extern void remcontacted __P((struct sockaddr *));
 extern void initctdtree __P((void));
 
 extern int check_recvdpkt __P((struct sockaddr *,
diff --git a/src/racoon/ipsec_doi.c b/src/racoon/ipsec_doi.c
index ba91f48..0aa1843 100644
--- a/src/racoon/ipsec_doi.c
+++ b/src/racoon/ipsec_doi.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: ipsec_doi.c,v 1.46 2010/12/14 17:57:31 tteras Exp $	*/
+/*	$NetBSD: ipsec_doi.c,v 1.23.4.10 2009/06/19 07:32:52 tteras Exp $	*/
 
 /* Id: ipsec_doi.c,v 1.55 2006/08/17 09:20:41 vanhu Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -83,6 +83,9 @@
 #ifdef ENABLE_NATT
 #include "nattraversal.h"
 #endif
+#ifdef ENABLE_HYBRID
+static int switch_authmethod(int);
+#endif
 
 #ifdef HAVE_GSSAPI
 #include <iconv.h>
@@ -94,19 +97,19 @@
 #endif
 #endif
 
-static vchar_t *get_ph1approval __P((struct ph1handle *, u_int32_t, u_int32_t,
-				     struct prop_pair **));
-static int get_ph1approvalx __P((struct remoteconf *, void *));
+int verbose_proposal_check = 1;
 
-static int t2isakmpsa __P((struct isakmp_pl_t *, struct isakmpsa *, u_int32_t));
+static vchar_t *get_ph1approval __P((struct ph1handle *, struct prop_pair **));
+static struct isakmpsa *get_ph1approvalx __P((struct prop_pair *,
+	struct isakmpsa *, struct isakmpsa *, int));
+static void print_ph1mismatched __P((struct prop_pair *, struct isakmpsa *));
+static int t2isakmpsa __P((struct isakmp_pl_t *, struct isakmpsa *));
 static int cmp_aproppair_i __P((struct prop_pair *, struct prop_pair *));
 static struct prop_pair *get_ph2approval __P((struct ph2handle *,
 	struct prop_pair **));
 static struct prop_pair *get_ph2approvalx __P((struct ph2handle *,
 	struct prop_pair *));
 static void free_proppair0 __P((struct prop_pair *));
-static struct prop_pair ** get_proppair_and_doi_sit __P((vchar_t *, int,
-							 u_int32_t *, u_int32_t *));
 
 static int get_transform
 	__P((struct isakmp_pl_p *, struct prop_pair **, int *));
@@ -155,10 +158,12 @@
 static vchar_t *setph2proposal0 __P((const struct ph2handle *,
 	const struct saprop *, const struct saproto *));
 
-struct ph1approvalx_ctx {
-	struct prop_pair *p;
-	struct isakmpsa *sa;
-};
+static vchar_t *getidval __P((int, vchar_t *));
+
+#ifdef HAVE_GSSAPI
+static struct isakmpsa *fixup_initiator_sa __P((struct isakmpsa *,
+	struct isakmpsa *));
+#endif
 
 /*%%%*/
 /*
@@ -177,82 +182,40 @@
 {
 	vchar_t *newsa;		/* new SA payload approved. */
 	struct prop_pair **pair;
-	u_int32_t doitype, sittype;
 
 	/* get proposal pair */
-	pair = get_proppair_and_doi_sit(sa, IPSECDOI_TYPE_PH1,
-					&doitype, &sittype);
+	pair = get_proppair(sa, IPSECDOI_TYPE_PH1);
 	if (pair == NULL)
 		return -1;
 
 	/* check and get one SA for use */
-	newsa = get_ph1approval(iph1, doitype, sittype, pair);
+	newsa = get_ph1approval(iph1, pair);
+	
 	free_proppair(pair);
 
 	if (newsa == NULL)
 		return -1;
 
 	iph1->sa_ret = newsa;
+
 	return 0;
 }
 
-static void
-print_ph1proposal(pair, s)
-	struct prop_pair *pair;
-	struct isakmpsa *s;
-{
-	struct isakmp_pl_p *prop = pair->prop;
-	struct isakmp_pl_t *trns = pair->trns;
-
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n",
-	     prop->p_no, s_ipsecdoi_proto(prop->proto_id),
-	     prop->spi_size, prop->num_t);
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "trns#=%d, trns-id=%s\n",
-	     trns->t_no, s_ipsecdoi_trns(prop->proto_id, trns->t_id));
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  lifetime = %ld\n", (long) s->lifetime);
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  lifebyte = %zu\n", s->lifebyte);
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  enctype = %s\n",
-	     s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, s->enctype));
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  encklen = %d\n", s->encklen);
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  hashtype = %s\n",
-	     s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, s->hashtype));
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  authmethod = %s\n",
-	     s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, s->authmethod));
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "  dh_group = %s\n",
-	     s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, s->dh_group));
-}
-
-
 /*
  * acceptable check for remote configuration.
  * return a new SA payload to be reply to peer.
  */
-
 static vchar_t *
-get_ph1approval(iph1, doitype, sittype, pair)
+get_ph1approval(iph1, pair)
 	struct ph1handle *iph1;
-	u_int32_t doitype, sittype;
 	struct prop_pair **pair;
 {
 	vchar_t *newsa;
-	struct ph1approvalx_ctx ctx;
+	struct isakmpsa *sa, tsa;
 	struct prop_pair *s, *p;
-	struct rmconfselector rmsel;
-	struct isakmpsa *sa;
+	int prophlen;
 	int i;
 
-	memset(&rmsel, 0, sizeof(rmsel));
-	rmsel.remote = iph1->remote;
-
 	if (iph1->approval) {
 		delisakmpsa(iph1->approval);
 		iph1->approval = NULL;
@@ -262,35 +225,42 @@
 		if (pair[i] == NULL)
 			continue;
 		for (s = pair[i]; s; s = s->next) {
+			prophlen = 
+			    sizeof(struct isakmp_pl_p) + s->prop->spi_size;
+
 			/* compare proposal and select one */
 			for (p = s; p; p = p->tnext) {
-				struct isakmp_pl_p *prop = p->prop;
-
-				sa = newisakmpsa();
-				ctx.p = p;
-				ctx.sa = sa;
-				if (t2isakmpsa(p->trns, sa,
-					       iph1->vendorid_mask) < 0)
-					continue;
-				print_ph1proposal(p, sa);
-				if (iph1->rmconf != NULL) {
-					if (get_ph1approvalx(iph1->rmconf, &ctx))
-						goto found;
-				} else {
-					if (enumrmconf(&rmsel, get_ph1approvalx, &ctx))
-						goto found;
-				}
-				delisakmpsa(sa);
+				if ((sa = get_ph1approvalx(p, 
+				    iph1->rmconf->proposal, &tsa, 
+				    iph1->rmconf->pcheck_level)) != NULL)
+					goto found;
 			}
 		}
 	}
 
+	/*
+	 * if there is no suitable proposal, racoon complains about all of
+	 * mismatched items in those proposal.
+	 */
+	if (verbose_proposal_check) {
+		for (i = 0; i < MAXPROPPAIRLEN; i++) {
+			if (pair[i] == NULL)
+				continue;
+			for (s = pair[i]; s; s = s->next) {
+				prophlen = sizeof(struct isakmp_pl_p)
+						+ s->prop->spi_size;
+				for (p = s; p; p = p->tnext) {
+					print_ph1mismatched(p,
+						iph1->rmconf->proposal);
+				}
+			}
+		}
+	}
 	plog(LLV_ERROR, LOCATION, NULL, "no suitable proposal found.\n");
 
 	return NULL;
 
 found:
-	sa = ctx.sa;
 	plog(LLV_DEBUG, LOCATION, NULL, "an acceptable proposal found.\n");
 
 	/* check DH group settings */
@@ -307,7 +277,7 @@
 
 	if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) {
 		sa->dhgrp = NULL;
-		delisakmpsa(sa);
+		racoon_free(sa);
 		return NULL;
 	}
 
@@ -316,16 +286,20 @@
 	if (sa->gssid != NULL)
 		plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n",
 		    (int)sa->gssid->l, sa->gssid->v);
-	if (iph1->side == INITIATOR) {
+	if (iph1-> side == INITIATOR) {
 		if (iph1->rmconf->proposal->gssid != NULL)
 			iph1->gi_i = vdup(iph1->rmconf->proposal->gssid);
-		if (sa->gssid != NULL)
-			iph1->gi_r = vdup(sa->gssid);
+		if (tsa.gssid != NULL)
+			iph1->gi_r = vdup(tsa.gssid);
+		iph1->approval = fixup_initiator_sa(sa, &tsa);
 	} else {
-		if (sa->gssid != NULL) {
-			iph1->gi_r = vdup(sa->gssid);
+		if (tsa.gssid != NULL) {
+			iph1->gi_r = vdup(tsa.gssid);
 			iph1->gi_i = gssapi_get_id(iph1);
+			if (sa->gssid == NULL && iph1->gi_i != NULL)
+				sa->gssid = vdup(iph1->gi_i);
 		}
+		iph1->approval = sa;
 	}
 	if (iph1->gi_i != NULL)
 		plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n",
@@ -333,15 +307,19 @@
 	if (iph1->gi_r != NULL)
 		plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n",
 		    (int)iph1->gi_r->l, iph1->gi_r->v);
+#else
+	iph1->approval = sa;
 #endif
-	plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n",
-	     s_oakley_attr_method(sa->authmethod));
+	if(iph1->approval) {
+		plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n",
+		    s_oakley_attr_method(iph1->approval->authmethod));
+	}
 
-	newsa = get_sabyproppair(doitype, sittype, p);
-	if (newsa == NULL)
-		delisakmpsa(sa);
-	else
-		iph1->approval = sa;
+	newsa = get_sabyproppair(p, iph1);
+	if (newsa == NULL){
+		delisakmpsa(iph1->approval);
+		iph1->approval = NULL;
+	}
 
 	return newsa;
 }
@@ -349,57 +327,228 @@
 /*
  * compare peer's single proposal and all of my proposal.
  * and select one if suiatable.
+ * p       : one of peer's proposal.
+ * proposal: my proposals.
  */
-static int
-get_ph1approvalx(rmconf, ctx)
-	struct remoteconf *rmconf;
-	void *ctx;
+static struct isakmpsa *
+get_ph1approvalx(p, proposal, sap, check_level)
+	struct prop_pair *p;
+	struct isakmpsa *proposal, *sap;
+	int check_level;
 {
-	struct ph1approvalx_ctx *pctx = (struct ph1approvalx_ctx *) ctx;
-	struct isakmpsa *sa;
+	struct isakmp_pl_p *prop = p->prop;
+	struct isakmp_pl_t *trns = p->trns;
+	struct isakmpsa sa, *s, *tsap;
+	int authmethod;
 
-	/* do the hard work */
-	sa = checkisakmpsa(rmconf->pcheck_level, pctx->sa, rmconf->proposal);
-	if (sa == NULL)
-		return 0;
+	plog(LLV_DEBUG, LOCATION, NULL,
+       		"prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n",
+		prop->p_no, s_ipsecdoi_proto(prop->proto_id),
+		prop->spi_size, prop->num_t);
 
-	/* duplicate and modify the found SA to match proposal */
-	sa = dupisakmpsa(sa);
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"trns#=%d, trns-id=%s\n",
+		trns->t_no,
+		s_ipsecdoi_trns(prop->proto_id, trns->t_id));
 
-	switch (rmconf->pcheck_level) {
-	case PROP_CHECK_OBEY:
-		sa->lifetime = pctx->sa->lifetime;
-		sa->lifebyte = pctx->sa->lifebyte;
-		sa->encklen = pctx->sa->encklen;
-		break;
-	case PROP_CHECK_CLAIM:
-	case PROP_CHECK_STRICT:
-		if (pctx->sa->lifetime < sa->lifetime)
-			sa->lifetime = pctx->sa->lifetime;
-		if (pctx->sa->lifebyte < sa->lifebyte)
-			sa->lifebyte = pctx->sa->lifebyte;
-		if (pctx->sa->encklen > sa->encklen)
-			sa->encklen = pctx->sa->encklen;
-		break;
-	default:
-		break;
+	tsap = sap != NULL ? sap : &sa;
+
+	memset(tsap, 0, sizeof(*tsap));
+	if (t2isakmpsa(trns, tsap) < 0)
+		return NULL;
+	for (s = proposal; s != NULL; s = s->next) {
+#ifdef ENABLE_HYBRID
+		authmethod = switch_authmethod(s->authmethod);
+#else
+		authmethod = s->authmethod;
+#endif
+		plog(LLV_DEBUG, LOCATION, NULL, "Compared: DB:Peer\n");
+		plog(LLV_DEBUG, LOCATION, NULL, "(lifetime = %ld:%ld)\n",
+			(long)s->lifetime, (long)tsap->lifetime);
+		plog(LLV_DEBUG, LOCATION, NULL, "(lifebyte = %zu:%zu)\n",
+			s->lifebyte, tsap->lifebyte);
+		plog(LLV_DEBUG, LOCATION, NULL, "enctype = %s:%s\n",
+			s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
+					s->enctype),
+			s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
+					tsap->enctype));
+		plog(LLV_DEBUG, LOCATION, NULL, "(encklen = %d:%d)\n",
+			s->encklen, tsap->encklen);
+		plog(LLV_DEBUG, LOCATION, NULL, "hashtype = %s:%s\n",
+			s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
+					s->hashtype),
+			s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
+					tsap->hashtype));
+		plog(LLV_DEBUG, LOCATION, NULL, "authmethod = %s:%s\n",
+			s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
+					s->authmethod),
+			s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
+					tsap->authmethod));
+		plog(LLV_DEBUG, LOCATION, NULL, "dh_group = %s:%s\n",
+			s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
+					s->dh_group),
+			s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
+					tsap->dh_group));
+#if 0
+		/* XXX to be considered ? */
+		if (tsap->lifebyte > s->lifebyte) ;
+#endif
+		/*
+		 * if responder side and peer's key length in proposal
+		 * is bigger than mine, it might be accepted.
+		 */
+		if(tsap->enctype == s->enctype &&
+		    tsap->authmethod == authmethod &&
+		    tsap->hashtype == s->hashtype &&
+		    tsap->dh_group == s->dh_group &&
+		    tsap->encklen == s->encklen) {
+			switch(check_level) {
+			case PROP_CHECK_OBEY:
+				goto found;
+				break;
+
+			case PROP_CHECK_STRICT:
+				if ((tsap->lifetime > s->lifetime) ||
+				    (tsap->lifebyte > s->lifebyte))
+					continue;
+				goto found;
+				break;
+
+			case PROP_CHECK_CLAIM:
+				if (tsap->lifetime < s->lifetime)
+					s->lifetime = tsap->lifetime;
+				if (tsap->lifebyte < s->lifebyte)
+					s->lifebyte = tsap->lifebyte;
+				goto found;
+				break;
+
+			case PROP_CHECK_EXACT:
+				if ((tsap->lifetime != s->lifetime) ||
+				    (tsap->lifebyte != s->lifebyte))
+					continue;
+				goto found;
+				break;
+
+			default:
+				plog(LLV_ERROR, LOCATION, NULL, 
+				    "Unexpected proposal_check value\n");
+				continue;
+				break;
+			}
+		}
 	}
 
-	/* replace the proposal with our approval sa */
-	delisakmpsa(pctx->sa);
-	pctx->sa = sa;
+found:
+	if (tsap->dhgrp != NULL){
+		oakley_dhgrp_free(tsap->dhgrp);
+		tsap->dhgrp = NULL;
+	}
 
-	return 1;
+	if ((s = dupisakmpsa(s)) != NULL) {
+		switch(check_level) {
+		case PROP_CHECK_OBEY:
+			s->lifetime = tsap->lifetime;
+			s->lifebyte = tsap->lifebyte;
+			break;
+
+		case PROP_CHECK_STRICT:
+			s->lifetime = tsap->lifetime;
+			s->lifebyte = tsap->lifebyte;
+			break;
+
+		case PROP_CHECK_CLAIM:
+			if (tsap->lifetime < s->lifetime)
+				s->lifetime = tsap->lifetime;
+			if (tsap->lifebyte < s->lifebyte)
+				s->lifebyte = tsap->lifebyte;
+			break;
+
+		default:
+			break;
+		}
+	}
+	return s;
+}
+
+/*
+ * print all of items in peer's proposal which are mismatched to my proposal.
+ * p       : one of peer's proposal.
+ * proposal: my proposals.
+ */
+static void
+print_ph1mismatched(p, proposal)
+	struct prop_pair *p;
+	struct isakmpsa *proposal;
+{
+	struct isakmpsa sa, *s;
+
+	memset(&sa, 0, sizeof(sa));
+	if (t2isakmpsa(p->trns, &sa) < 0)
+		return;
+	for (s = proposal; s ; s = s->next) {
+		if (sa.enctype != s->enctype) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"rejected enctype: "
+				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
+				"%s:%s\n",
+				s->prop_no, s->trns_no,
+				p->prop->p_no, p->trns->t_no,
+				s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
+					s->enctype),
+				s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
+					sa.enctype));
+		}
+		if (sa.authmethod != s->authmethod) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"rejected authmethod: "
+				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
+				"%s:%s\n",
+				s->prop_no, s->trns_no,
+				p->prop->p_no, p->trns->t_no,
+				s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
+					s->authmethod),
+				s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
+					sa.authmethod));
+		}
+		if (sa.hashtype != s->hashtype) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"rejected hashtype: "
+				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
+				"%s:%s\n",
+				s->prop_no, s->trns_no,
+				p->prop->p_no, p->trns->t_no,
+				s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
+					s->hashtype),
+				s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
+					sa.hashtype));
+		}
+		if (sa.dh_group != s->dh_group) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"rejected dh_group: "
+				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
+				"%s:%s\n",
+				s->prop_no, s->trns_no,
+				p->prop->p_no, p->trns->t_no,
+				s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
+					s->dh_group),
+				s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
+					sa.dh_group));
+		}
+	}
+
+	if (sa.dhgrp != NULL){
+		oakley_dhgrp_free(sa.dhgrp);
+		sa.dhgrp=NULL;
+	}
 }
 
 /*
  * get ISAKMP data attributes
  */
 static int
-t2isakmpsa(trns, sa, vendorid_mask)
+t2isakmpsa(trns, sa)
 	struct isakmp_pl_t *trns;
 	struct isakmpsa *sa;
-	u_int32_t vendorid_mask;
 {
 	struct isakmp_data *d, *prev;
 	int flag, type;
@@ -469,11 +618,6 @@
 
 		case OAKLEY_ATTR_AUTH_METHOD:
 			sa->authmethod = ntohs(d->lorv);
-#ifdef HAVE_GSSAPI
-			if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB_REAL &&
-			    (vendorid_mask & VENDORID_GSSAPI_MASK))
-				sa->authmethod = OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB;
-#endif
 			break;
 
 		case OAKLEY_ATTR_GRP_DESC:
@@ -626,7 +770,7 @@
 				plog(LLV_DEBUG, LOCATION, NULL,
 				    "received old-style gss "
 				    "id '%.*s' (len %zu)\n",
-				    (int)sa->gssid->l, sa->gssid->v,
+				    (int)sa->gssid->l, sa->gssid->v, 
 				    sa->gssid->l);
 				error = 0;
 				goto out;
@@ -661,7 +805,7 @@
 			dst = sa->gssid->v;
 			dstleft = len / 2;
 
-			rv = iconv(cd, (__iconv_const char **)&src, &srcleft,
+			rv = iconv(cd, (__iconv_const char **)&src, &srcleft, 
 				   &dst, &dstleft);
 			if (rv != 0) {
 				if (rv == -1) {
@@ -747,11 +891,9 @@
 {
 	struct prop_pair **pair;
 	struct prop_pair *ret;
-	u_int32_t doitype, sittype;
 
 	/* get proposal pair */
-	pair = get_proppair_and_doi_sit(iph2->sa, IPSECDOI_TYPE_PH2,
-					&doitype, &sittype);
+	pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
 	if (pair == NULL)
 		return -1;
 
@@ -763,7 +905,7 @@
 
 	/* make a SA to be replayed. */
 	/* SPI must be updated later. */
-	iph2->sa_ret = get_sabyproppair(doitype, sittype, ret);
+	iph2->sa_ret = get_sabyproppair(ret, iph2->ph1);
 	free_proppair0(ret);
 	if (iph2->sa_ret == NULL)
 		return -1;
@@ -787,11 +929,9 @@
 	int i, n, num;
 	int error = -1;
 	vchar_t *sa_ret = NULL;
-	u_int32_t doitype, sittype;
 
 	/* get proposal pair of SA sent. */
-	spair = get_proppair_and_doi_sit(iph2->sa, IPSECDOI_TYPE_PH2,
-					 &doitype, &sittype);
+	spair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
 	if (spair == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to get prop pair.\n");
@@ -832,7 +972,7 @@
 		plog(LLV_WARNING, LOCATION, NULL,
 			"invalid proposal number:%d received.\n", i);
 	}
-
+	
 
 	if (rpair[n]->tnext != NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -857,7 +997,7 @@
 
 	/* make a SA to be replayed. */
 	sa_ret = iph2->sa_ret;
-	iph2->sa_ret = get_sabyproppair(doitype, sittype, p);
+	iph2->sa_ret = get_sabyproppair(p, iph2->ph1);
 	free_proppair0(p);
 	if (iph2->sa_ret == NULL)
 		goto end;
@@ -1142,11 +1282,10 @@
  * get proposal pairs from SA payload.
  * tiny check for proposal payload.
  */
-static struct prop_pair **
-get_proppair_and_doi_sit(sa, mode, doitype, sittype)
+struct prop_pair **
+get_proppair(sa, mode)
 	vchar_t *sa;
 	int mode;
-	u_int32_t *doitype, *sittype;
 {
 	struct prop_pair **pair = NULL;
 	int num_p = 0;			/* number of proposal for use */
@@ -1168,14 +1307,10 @@
 	/* check DOI */
 	if (check_doi(ntohl(sab->doi)) < 0)
 		goto bad;
-	if (doitype != NULL)
-		*doitype = ntohl(sab->doi);
 
 	/* check SITUATION */
 	if (check_situation(ntohl(sab->sit)) < 0)
 		goto bad;
-	if (sittype != NULL)
-		*sittype = ntohl(sab->sit);
 
 	pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair));
 	if (pair == NULL) {
@@ -1311,15 +1446,6 @@
 	return NULL;
 }
 
-struct prop_pair **
-get_proppair(sa, mode)
-	vchar_t *sa;
-	int mode;
-{
-	return get_proppair_and_doi_sit(sa, mode, NULL, NULL);
-}
-
-
 /*
  * check transform payload.
  * OUT:
@@ -1434,9 +1560,9 @@
  * NOTE: this function make spi value clear.
  */
 vchar_t *
-get_sabyproppair(doitype, sittype, pair)
-	u_int32_t doitype, sittype;
+get_sabyproppair(pair, iph1)
 	struct prop_pair *pair;
+	struct ph1handle *iph1;
 {
 	vchar_t *newsa;
 	int newtlen;
@@ -1462,8 +1588,8 @@
 	((struct isakmp_gen *)bp)->len = htons(newtlen);
 
 	/* update some of values in SA header */
-	((struct ipsecdoi_sa_b *)bp)->doi = htonl(doitype);
-	((struct ipsecdoi_sa_b *)bp)->sit = htonl(sittype);
+	((struct ipsecdoi_sa_b *)bp)->doi = htonl(iph1->rmconf->doitype);
+	((struct ipsecdoi_sa_b *)bp)->sit = htonl(iph1->rmconf->sittype);
 	bp += sizeof(struct ipsecdoi_sa_b);
 
 	/* create proposal payloads */
@@ -1698,96 +1824,6 @@
 	return ld;
 }
 
-/*
- * parse responder-lifetime attributes from payload
- */
-int
-ipsecdoi_parse_responder_lifetime(notify, lifetime_sec, lifetime_kb)
-	struct isakmp_pl_n *notify;
-	u_int32_t *lifetime_sec;
-	u_int32_t *lifetime_kb;
-{
-	struct isakmp_data *d;
-	int flag, type, tlen, ld_type = -1;
-	u_int16_t lorv;
-	u_int32_t value;
-
-	tlen = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
-        d = (struct isakmp_data *)((char *)(notify + 1) +
-		notify->spi_size);
-
-	while (tlen >= sizeof(struct isakmp_data)) {
-		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
-		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
-		lorv = ntohs(d->lorv);
-
-		plog(LLV_DEBUG, LOCATION, NULL,
-			"type=%s, flag=0x%04x, lorv=%s\n",
-			s_ipsecdoi_attr(type), flag,
-			s_ipsecdoi_attr_v(type, lorv));
-
-		switch (type) {
-		case IPSECDOI_ATTR_SA_LD_TYPE:
-			if (! flag) {
-				plog(LLV_ERROR, LOCATION, NULL,
-					"must be TV when LD_TYPE.\n");
-				return -1;
-			}
-			ld_type = lorv;
-			break;
-		case IPSECDOI_ATTR_SA_LD:
-			if (flag)
-				value = lorv;
-			else if (lorv == 2)
-				value = ntohs(*(u_int16_t *)(d + 1));
-			else if (lorv == 4)
-				value = ntohl(*(u_int32_t *)(d + 1));
-			else {
-				plog(LLV_ERROR, LOCATION, NULL,
-					"payload length %d for lifetime "
-					"data length is unsupported.\n", lorv);
-				return -1;
-			}
-
-			switch (ld_type) {
-			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
-				if (lifetime_sec != NULL)
-					*lifetime_sec = value;
-				plog(LLV_INFO, LOCATION, NULL,
-					"received RESPONDER-LIFETIME: %d "
-					"seconds\n", value);
-				break;
-			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
-				if (lifetime_kb != NULL)
-					*lifetime_kb = value;
-				plog(LLV_INFO, LOCATION, NULL,
-					"received RESPONDER-LIFETIME: %d "
-					"kbytes\n", value);
-				break;
-			default:
-				plog(LLV_ERROR, LOCATION, NULL,
-					"lifetime data received without "
-					"lifetime data type.\n");
-				return -1;
-			}
-			break;
-		}
-
-		if (flag) {
-			tlen -= sizeof(*d);
-			d = (struct isakmp_data *)((char *)d
-				+ sizeof(*d));
-		} else {
-			tlen -= (sizeof(*d) + lorv);
-			d = (struct isakmp_data *)((char *)d
-				+ sizeof(*d) + lorv);
-		}
-	}
-
-	return 0;
-}
-
-
 /*%%%*/
 /*
  * check DOI
@@ -2094,12 +2130,11 @@
 #ifdef ENABLE_HYBRID
 			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
-#endif
-#if defined(ENABLE_HYBRID) || defined(HAVE_GSSAPI)
-				/* These two authentication method IDs overlap. */
+#if 0 /* Clashes with OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB */
 			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
-			/*case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:*/
 #endif
+#endif
+			case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
 				break;
 			case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
 #ifdef ENABLE_HYBRID
@@ -2316,7 +2351,7 @@
  				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
  					if (trns->t_id != IPSECDOI_AH_SHA256)
  						goto ahmismatch;
- 				}
+ 				}	
  				break;
  			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
  				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
@@ -2603,8 +2638,7 @@
  * NOT INCLUDING isakmp general header of SA payload
  */
 vchar_t *
-ipsecdoi_setph1proposal(rmconf, props)
-	struct remoteconf *rmconf;
+ipsecdoi_setph1proposal(props)
 	struct isakmpsa *props;
 {
 	vchar_t *mysa;
@@ -2624,8 +2658,8 @@
 
 	/* create SA payload */
 	/* not including isakmp general header */
-	((struct ipsecdoi_sa_b *)mysa->v)->doi = htonl(rmconf->doitype);
-	((struct ipsecdoi_sa_b *)mysa->v)->sit = htonl(rmconf->sittype);
+	((struct ipsecdoi_sa_b *)mysa->v)->doi = htonl(props->rmconf->doitype);
+	((struct ipsecdoi_sa_b *)mysa->v)->sit = htonl(props->rmconf->sittype);
 
 	(void)setph1prop(props, mysa->v + sizeof(struct ipsecdoi_sa_b));
 
@@ -2733,7 +2767,7 @@
 						OAKLEY_ATTR_SA_LD_TYPE_SEC);
 			if (sa->lifetime > 0xffff) {
 				p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
-						(caddr_t)&lifetime,
+						(caddr_t)&lifetime, 
 						sizeof(lifetime));
 			} else {
 				p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
@@ -2744,7 +2778,7 @@
 
 	if (sa->lifebyte) {
 		u_int32_t lifebyte = htonl((u_int32_t)sa->lifebyte);
-
+		
 		attrlen += sizeof(struct isakmp_data)
 			+ sizeof(struct isakmp_data);
 		if (sa->lifebyte > 0xffff)
@@ -2776,8 +2810,11 @@
 	if (sa->authmethod) {
 		int authmethod;
 
-		authmethod = isakmpsa_switch_authmethod(sa->authmethod);
-		authmethod &= 0xffff;
+#ifdef ENABLE_HYBRID
+		authmethod = switch_authmethod(sa->authmethod);
+#else
+		authmethod = sa->authmethod;
+#endif
 		attrlen += sizeof(struct isakmp_data);
 		if (buf)
 			p = isakmp_set_attr_l(p, OAKLEY_ATTR_AUTH_METHOD, authmethod);
@@ -2859,7 +2896,7 @@
 					goto gssid_done;
 				}
 				odst = dst;
-				rv = iconv(cd, (__iconv_const char **)&src,
+				rv = iconv(cd, (__iconv_const char **)&src, 
 				    &srcleft, &dst, &dstleft);
 				if (rv != 0) {
 					if (rv == -1) {
@@ -2952,7 +2989,7 @@
 	np_t = NULL;
 
 	for (tr = pr->head; tr; tr = tr->next) {
-
+	
 		switch (pr->proto_id) {
 		case IPSECDOI_PROTO_IPSEC_ESP:
 			/*
@@ -3200,9 +3237,7 @@
 
 	for (; pp; pp = pp->next) {
 		for (pr = pp->head; pr; pr = pr->next) {
-			if (pr->encmode != IPSECDOI_ATTR_ENC_MODE_TRNS &&
-			    pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC &&
-			    pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT)
+			if (pr->encmode != IPSECDOI_ATTR_ENC_MODE_TRNS)
 				return 0;
 		}
 	}
@@ -3562,6 +3597,8 @@
 	struct ph1handle *iph1;
 {
 	struct ipsecdoi_id_b *id_b;
+	struct sockaddr *sa;
+	caddr_t sa1, sa2;
 
 	if (iph1->id_p == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -3577,6 +3614,7 @@
 
 	id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
 
+#ifndef ANDROID_PATCHED
 	/* In main mode with pre-shared key, only address type can be used. */
 	if (iph1->etype == ISAKMP_ETYPE_IDENT &&
 	    iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) {
@@ -3588,6 +3626,7 @@
 			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
 		}
 	}
+#endif
 
 	/* if proper type for phase 1 ? */
 	switch (id_b->type) {
@@ -3631,12 +3670,73 @@
 		}
 	}
 
-	/* resolve remote configuration if not done yet */
-	if (resolveph1rmconf(iph1) < 0)
-		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+	/* compare with the ID if specified. */
+	if (genlist_next(iph1->rmconf->idvl_p, 0)) {
+		vchar_t *ident0 = NULL;
+		vchar_t ident;
+		struct idspec *id;
+		struct genlist_entry *gpb;
 
-	if (iph1->rmconf == NULL)
-		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+		for (id = genlist_next (iph1->rmconf->idvl_p, &gpb); id; id = genlist_next (0, &gpb)) {
+			/* check the type of both IDs */
+			if (id->idtype != doi2idtype(id_b->type))
+				continue;  /* ID type mismatch */
+			if (id->id == 0)
+				goto matched;
+
+			/* compare defined ID with the ID sent by peer. */
+			if (ident0 != NULL)
+				vfree(ident0);
+			ident0 = getidval(id->idtype, id->id);
+
+			switch (id->idtype) {
+			case IDTYPE_ASN1DN:
+				ident.v = iph1->id_p->v + sizeof(*id_b);
+				ident.l = iph1->id_p->l - sizeof(*id_b);
+				if (eay_cmp_asn1dn(ident0, &ident) == 0)
+					goto matched;
+				break;
+			case IDTYPE_ADDRESS:
+				sa = (struct sockaddr *)ident0->v;
+				sa2 = (caddr_t)(id_b + 1);
+				switch (sa->sa_family) {
+				case AF_INET:
+					if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in_addr))
+						continue;  /* ID value mismatch */
+					sa1 = (caddr_t)&((struct sockaddr_in *)sa)->sin_addr;
+					if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0)
+						goto matched;
+					break;
+#ifdef INET6
+				case AF_INET6:
+					if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in6_addr))
+						continue;  /* ID value mismatch */
+					sa1 = (caddr_t)&((struct sockaddr_in6 *)sa)->sin6_addr;
+					if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0)
+						goto matched;
+					break;
+#endif
+				default:
+					break;
+				}
+				break;
+			default:
+				if (memcmp(ident0->v, id_b + 1, ident0->l) == 0)
+					goto matched;
+				break;
+			}
+		}
+		if (ident0 != NULL) {
+			vfree(ident0);
+			ident0 = NULL;
+		}
+		plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n");
+		if (iph1->rmconf->verify_identifier)
+			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+matched: /* ID value match */
+		if (ident0 != NULL)
+			vfree(ident0);
+	}
 
 	return 0;
 }
@@ -3663,15 +3763,15 @@
 	switch (iph1->rmconf->idvtype) {
 	case IDTYPE_FQDN:
 		id_b.type = IPSECDOI_ID_FQDN;
-		ident = vdup(iph1->rmconf->idv);
+		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
 		break;
 	case IDTYPE_USERFQDN:
 		id_b.type = IPSECDOI_ID_USER_FQDN;
-		ident = vdup(iph1->rmconf->idv);
+		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
 		break;
 	case IDTYPE_KEYID:
 		id_b.type = IPSECDOI_ID_KEY_ID;
-		ident = vdup(iph1->rmconf->idv);
+		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
 		break;
 	case IDTYPE_ASN1DN:
 		id_b.type = IPSECDOI_ID_DER_ASN1_DN;
@@ -3684,7 +3784,7 @@
 					"failed to get own CERT.\n");
 				goto err;
 			}
-			ident = eay_get_x509asn1subjectname(iph1->cert);
+			ident = eay_get_x509asn1subjectname(&iph1->cert->cert);
 		}
 		break;
 	case IDTYPE_ADDRESS:
@@ -3729,7 +3829,7 @@
 		if (!ident) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"failed to get ID buffer.\n");
-			return -1;
+			return 0;
 		}
 		memcpy(ident->v, p, ident->l);
 	    }
@@ -3737,7 +3837,7 @@
 	if (!ident) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to get ID buffer.\n");
-		return -1;
+		return 0;
 	}
 
 	ret = vmalloc(sizeof(id_b) + ident->l);
@@ -3765,6 +3865,21 @@
 	return -1;
 }
 
+static vchar_t *
+getidval(type, val)
+	int type;
+	vchar_t *val;
+{
+	vchar_t *new = NULL;
+
+	if (val)
+		new = vdup(val);
+	else if (lcconf->ident[type])
+		new = vdup(lcconf->ident[type]);
+
+	return new;
+}
+
 /* it's only called by cfparse.y. */
 int
 set_identifier(vpp, type, value)
@@ -3807,9 +3922,9 @@
 		memcpy(new->v, value->v, new->l);
 		break;
 	case IDTYPE_KEYID:
-		/*
+		/* 
 		 * If no qualifier is specified: IDQUAL_UNSPEC. It means
-		 * to use a file for backward compatibility sake.
+		 * to use a file for backward compatibility sake. 
 		 */
 		switch(qual) {
 		case IDQUAL_FILE:
@@ -3834,7 +3949,6 @@
 				memcpy(new->v + tlen, b, len);
 				tlen += len;
 			}
-			fclose(fp);
 			break;
 		}
 
@@ -3854,7 +3968,7 @@
 			return -1;
 		}
 		break;
-
+	
 	case IDTYPE_ADDRESS: {
 		struct sockaddr *sa;
 
@@ -3898,7 +4012,7 @@
 
 			xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l);
 			bio = BIO_new(BIO_s_mem());
-
+			
 			X509_NAME_print_ex(bio, xn, 0, 0);
 			len = BIO_get_mem_data(bio, &ptr);
 			save = ptr[len];
@@ -3938,25 +4052,8 @@
 		return -1;
 	}
 
-	if (!ipsecdoi_transportmode(iph2->proposal))
-		iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src,
-				sp->spidx.prefs, sp->spidx.ul_proto);
-	else if (iph2->sa_src != NULL) {
-		/* He have a specific hint indicating that the transport
-		 * mode SA will be negotiated using addresses that differ
-		 * with the one from the SA. We need to indicate that to
-		 * our peer by setting the SA address as ID.
-		 * This is typically the case for the bootstrapping of the
-		 * transport mode SA protecting BU/BA for MIPv6 traffic
-		 *
-		 * --arno*/
-		iph2->id = ipsecdoi_sockaddr2id(iph2->sa_src,
-						IPSECDOI_PREFIX_HOST,
-						sp->spidx.ul_proto);
-	} else
-		iph2->id = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST,
-						sp->spidx.ul_proto);
-
+	iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src,
+					sp->spidx.prefs, sp->spidx.ul_proto);
 	if (iph2->id == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to get ID for %s\n",
@@ -3967,22 +4064,8 @@
 		s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id->v)->type));
 
 	/* remote side */
-#ifdef ANDROID_PATCHED
-	if (1)
-#else
-	if (!ipsecdoi_transportmode(iph2->proposal))
-#endif
-		iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst,
+	iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst,
 				sp->spidx.prefd, sp->spidx.ul_proto);
-	else if (iph2->sa_dst != NULL) {
-		/* See comment above for local side. */
-		iph2->id_p = ipsecdoi_sockaddr2id(iph2->sa_dst,
-						  IPSECDOI_PREFIX_HOST,
-						  sp->spidx.ul_proto);
-	} else
-		iph2->id_p = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST,
-			sp->spidx.ul_proto);
-
 	if (iph2->id_p == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to get ID for %s\n",
@@ -4019,7 +4102,7 @@
 	switch (saddr->sa_family) {
 	case AF_INET:
 		len1 = sizeof(struct in_addr);
-		if (prefixlen >= (sizeof(struct in_addr) << 3)) {
+		if (prefixlen == (sizeof(struct in_addr) << 3)) {
 			type = IPSECDOI_ID_IPV4_ADDR;
 			len2 = 0;
 		} else {
@@ -4032,7 +4115,7 @@
 #ifdef INET6
 	case AF_INET6:
 		len1 = sizeof(struct in6_addr);
-		if (prefixlen >= (sizeof(struct in6_addr) << 3)) {
+		if (prefixlen == (sizeof(struct in6_addr) << 3)) {
 			type = IPSECDOI_ID_IPV6_ADDR;
 			len2 = 0;
 		} else {
@@ -4077,7 +4160,7 @@
 
 	/* set prefix */
 	if (len2) {
-		u_char *p = (unsigned char *) new->v +
+		u_char *p = (unsigned char *) new->v + 
 			sizeof(struct ipsecdoi_id_b) + len1;
 		u_int bits = prefixlen;
 
@@ -4148,10 +4231,10 @@
 	port = ((struct sockaddr_in *)(laddr))->sin_port;
 	((struct ipsecdoi_id_b *)new->v)->port =
 		port == IPSEC_PORT_ANY ? 0 : port;
-	memcpy(new->v + sizeof(struct ipsecdoi_id_b),
-	       (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr,
+	memcpy(new->v + sizeof(struct ipsecdoi_id_b), 
+	       (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr, 
 	       len1);
-	memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1,
+	memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1, 
 	       (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr,
 	       len2);
 	return new;
@@ -4170,14 +4253,9 @@
 	u_int8_t *prefixlen;
 	u_int16_t *ul_proto;
 {
-	struct ipsecdoi_id_b *id_b = NULL;
+	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)buf->v;
 	u_int plen = 0;
 
-	if (buf == NULL)
-		return ISAKMP_INTERNAL_ERROR;
-
-	id_b = (struct ipsecdoi_id_b *)buf->v;
-
 	/*
 	 * When a ID payload of subnet type with a IP address of full bit
 	 * masked, it has to be processed as host address.
@@ -4212,11 +4290,6 @@
 				: id_b->port);		/* see sockaddr2id() */
 		memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr,
 			buf->v + sizeof(*id_b), sizeof(struct in6_addr));
-		((struct sockaddr_in6 *)saddr)->sin6_scope_id =
-			(IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)saddr)->sin6_addr)
-				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
-				: 0);
-
 		break;
 #endif
 	default:
@@ -4310,20 +4383,29 @@
 	char *dat;
 	static char buf[BUFLEN];
 	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v;
-	union sockaddr_any saddr;
+	struct sockaddr_storage saddr_storage;
+	struct sockaddr        *saddr;
+	struct sockaddr_in     *saddr_in;
+	struct sockaddr_in6    *saddr_in6;
 	u_int plen = 0;
 
+	saddr     = (struct sockaddr *)&saddr_storage;
+	saddr_in  = (struct sockaddr_in *)&saddr_storage;
+	saddr_in6 = (struct sockaddr_in6 *)&saddr_storage;
+
+	
 	switch (id_b->type) {
 	case IPSECDOI_ID_IPV4_ADDR:
 	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
 	case IPSECDOI_ID_IPV4_ADDR_RANGE:
 
 #ifndef __linux__
-		saddr.sa.sa_len = sizeof(struct sockaddr_in);
+		saddr->sa_len = sizeof(struct sockaddr_in);
 #endif
-		saddr.sa.sa_family = AF_INET;
-		saddr.sin.sin_port = IPSEC_PORT_ANY;
-		memcpy(&saddr.sin.sin_addr,
+		saddr->sa_family = AF_INET;
+
+		saddr_in->sin_port = IPSEC_PORT_ANY;
+		memcpy(&saddr_in->sin_addr,
 			id->v + sizeof(*id_b), sizeof(struct in_addr));
 		break;
 #ifdef INET6
@@ -4332,14 +4414,15 @@
 	case IPSECDOI_ID_IPV6_ADDR_RANGE:
 
 #ifndef __linux__
-		saddr.sa.sa_len = sizeof(struct sockaddr_in6);
+		saddr->sa_len = sizeof(struct sockaddr_in6);
 #endif
-		saddr.sa.sa_family = AF_INET6;
-		saddr.sin6.sin6_port = IPSEC_PORT_ANY;
-		memcpy(&saddr.sin6.sin6_addr,
+		saddr->sa_family = AF_INET6;
+
+		saddr_in6->sin6_port = IPSEC_PORT_ANY;
+		memcpy(&saddr_in6->sin6_addr,
 			id->v + sizeof(*id_b), sizeof(struct in6_addr));
-		saddr.sin6.sin6_scope_id =
-			(IN6_IS_ADDR_LINKLOCAL(&saddr.sin6.sin6_addr)
+		saddr_in6->sin6_scope_id =
+			(IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr)
 				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
 				: 0);
 		break;
@@ -4351,7 +4434,7 @@
 #ifdef INET6
 	case IPSECDOI_ID_IPV6_ADDR:
 #endif
-		len = snprintf( buf, BUFLEN, "%s", saddrwop2str(&saddr.sa));
+		len = snprintf( buf, BUFLEN, "%s", saddrwop2str(saddr));
 		break;
 
 	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
@@ -4407,44 +4490,47 @@
 			plen += l;
 		}
 
-		len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr.sa), plen);
+		len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(saddr), plen);
 	    }
 		break;
 
 	case IPSECDOI_ID_IPV4_ADDR_RANGE:
 
-		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr.sa));
+		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr));
 
 #ifndef __linux__
-		saddr.sa.sa_len = sizeof(struct sockaddr_in);
+		saddr->sa_len = sizeof(struct sockaddr_in);
 #endif
-		saddr.sa.sa_family = AF_INET;
-		saddr.sin.sin_port = IPSEC_PORT_ANY;
-		memcpy(&saddr.sin.sin_addr,
+		saddr->sa_family = AF_INET;
+		saddr_in->sin_port = IPSEC_PORT_ANY;
+		memcpy(&saddr_in->sin_addr,
 			id->v + sizeof(*id_b) + sizeof(struct in_addr),
 			sizeof(struct in_addr));
 
-		len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa));
+		len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr));
+
 		break;
 
 #ifdef INET6
 	case IPSECDOI_ID_IPV6_ADDR_RANGE:
-		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr.sa));
+
+		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr));
 
 #ifndef __linux__
-		saddr.sa.sa_len = sizeof(struct sockaddr_in6);
+		saddr->sa_len = sizeof(struct sockaddr_in6);
 #endif
-		saddr.sa.sa_family = AF_INET6;
-		saddr.sin6.sin6_port = IPSEC_PORT_ANY;
-		memcpy(&saddr.sin6.sin6_addr,
+		saddr->sa_family = AF_INET6;
+		saddr_in6->sin6_port = IPSEC_PORT_ANY;
+		memcpy(&saddr_in6->sin6_addr,
 			id->v + sizeof(*id_b) + sizeof(struct in6_addr),
 			sizeof(struct in6_addr));
-		saddr.sin6.sin6_scope_id =
-			(IN6_IS_ADDR_LINKLOCAL(&saddr.sin6.sin6_addr)
+		saddr_in6->sin6_scope_id =
+			(IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr)
 				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
 				: 0);
 
-		len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa));
+		len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr));
+
 		break;
 #endif
 
@@ -4749,12 +4835,24 @@
 	return -1;
 }
 
+#ifdef HAVE_GSSAPI
+struct isakmpsa *
+fixup_initiator_sa(match, received)
+	struct isakmpsa *match, *received;
+{
+	if (received->gssid != NULL)
+		match->gssid = vdup(received->gssid);
+
+	return match;
+}
+#endif
+
 static int rm_idtype2doi[] = {
 	255,				/* IDTYPE_UNDEFINED, 0 */
 	IPSECDOI_ID_FQDN,		/* IDTYPE_FQDN, 1 */
 	IPSECDOI_ID_USER_FQDN,		/* IDTYPE_USERFQDN, 2 */
 	IPSECDOI_ID_KEY_ID,		/* IDTYPE_KEYID, 3 */
-	255,    /*			   IDTYPE_ADDRESS, 4
+	255,    /*			   IDTYPE_ADDRESS, 4 
 		 * it expands into 4 types by another function. */
 	IPSECDOI_ID_DER_ASN1_DN,	/* IDTYPE_ASN1DN, 5 */
 };
@@ -4799,3 +4897,39 @@
 	}
 	/*NOTREACHED*/
 }
+
+#ifdef ENABLE_HYBRID
+static int
+switch_authmethod(authmethod)
+	int authmethod;
+{
+	switch(authmethod) {
+	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
+		break;
+	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I;
+		break;
+	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
+		break;
+	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
+		break;
+	/* Those are not implemented */
+	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
+		break;
+	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I;
+		break;
+	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I;
+		break;
+	default:
+		break;
+	}
+
+	return authmethod;
+}
+#endif
diff --git a/src/racoon/ipsec_doi.h b/src/racoon/ipsec_doi.h
index e3128f9..21dd93d 100644
--- a/src/racoon/ipsec_doi.h
+++ b/src/racoon/ipsec_doi.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_doi.h,v 1.12 2009/03/12 10:57:26 tteras Exp $	*/
+/*	$NetBSD: ipsec_doi.h,v 1.9 2006/12/09 05:52:57 manu Exp $	*/
 
 /* Id: ipsec_doi.h,v 1.15 2006/08/11 16:06:30 vanhu Exp */
 
@@ -34,8 +34,6 @@
 #ifndef _IPSEC_DOI_H
 #define _IPSEC_DOI_H
 
-#include "isakmp.h"
-
 /* refered to RFC2407 */
 
 #define IPSEC_DOI 1
@@ -199,12 +197,6 @@
 #define IPSECDOI_TYPE_PH1	0
 #define IPSECDOI_TYPE_PH2	1
 
-/*
- * Prefix that will make ipsecdoi_sockaddr2id() generate address type
- * identities without knowning the exact length of address.
- */
-#define IPSECDOI_PREFIX_HOST	0xff
-
 struct isakmpsa;
 struct ipsecdoi_pl_sa;
 struct saprop;
@@ -217,7 +209,7 @@
 extern int ipsecdoi_checkph2proposal __P((struct ph2handle *));
 
 extern struct prop_pair **get_proppair __P((vchar_t *, int));
-extern vchar_t *get_sabyproppair __P((u_int32_t, u_int32_t, struct prop_pair *));
+extern vchar_t *get_sabyproppair __P((struct prop_pair *, struct ph1handle *));
 extern int ipsecdoi_updatespi __P((struct ph2handle *iph2));
 extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *));
 extern int ipsecdoi_chkcmpids( const vchar_t *, const vchar_t *, int );
@@ -233,8 +225,7 @@
 extern vchar_t *ipsecdoi_sockrange2id __P((	struct sockaddr *,
 	struct sockaddr *, u_int));
 
-extern vchar_t *ipsecdoi_setph1proposal __P((struct remoteconf *,
-					     struct isakmpsa *));
+extern vchar_t *ipsecdoi_setph1proposal __P((struct isakmpsa *));
 extern int ipsecdoi_setph2proposal __P((struct ph2handle *));
 extern int ipsecdoi_transportmode __P((struct saprop *));
 extern int ipsecdoi_get_defaultlifetime __P((void));
@@ -248,8 +239,5 @@
 extern int idtype2doi __P((int));
 extern int doi2idtype __P((int));
 
-extern int ipsecdoi_parse_responder_lifetime __P((struct isakmp_pl_n *notify,
-	u_int32_t *lifetime_sec, u_int32_t *liftime_kb));
-
 
 #endif /* _IPSEC_DOI_H */
diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c
index 048ca71..12eb5a0 100644
--- a/src/racoon/isakmp.c
+++ b/src/racoon/isakmp.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: isakmp.c,v 1.71 2011/03/15 13:20:14 vanhu Exp $	*/
+/*	$NetBSD: isakmp.c,v 1.20.6.13 2008/09/25 09:34:39 vanhu Exp $	*/
 
 /* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -72,7 +72,6 @@
 #include "plog.h"
 #include "sockmisc.h"
 #include "schedule.h"
-#include "session.h"
 #include "debug.h"
 
 #include "remoteconf.h"
@@ -89,9 +88,6 @@
 #include "pfkey.h"
 #include "crypto_openssl.h"
 #include "policy.h"
-#include "algorithm.h"
-#include "proposal.h"
-#include "sainfo.h"
 #include "isakmp_ident.h"
 #include "isakmp_agg.h"
 #include "isakmp_base.h"
@@ -120,6 +116,9 @@
 #  ifndef SOL_UDP
 #   define SOL_UDP 17
 #  endif
+#ifdef ANDROID_CHANGES
+#define __linux
+#endif
 # endif /* __linux__ */
 # if defined(__NetBSD__) || defined(__FreeBSD__) ||	\
   (defined(__APPLE__) && defined(__MACH__))
@@ -138,34 +137,34 @@
 static int (*ph1exchange[][2][PHASE1ST_MAX])
 	__P((struct ph1handle *, vchar_t *)) = {
  /* error */
- { { 0 }, { 0 }, },
+ { {}, {}, },
  /* Identity Protection exchange */
  {
   { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send,
-    ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, nostate1,},
+    ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, },
   { nostate1, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send,
-    ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, nostate1, },
+    ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, },
  },
  /* Aggressive exchange */
  {
   { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send,
-    nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, },
+    nostate1, nostate1, nostate1, nostate1, nostate1, },
   { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send,
-    nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, },
+    nostate1, nostate1, nostate1, nostate1, nostate1, },
  },
  /* Base exchange */
  {
   { nostate1, base_i1send, nostate1, base_i2recv, base_i2send,
-    base_i3recv, base_i3send, nostate1, nostate1, nostate1, nostate1, },
+    base_i3recv, base_i3send, nostate1, nostate1, nostate1, },
   { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send,
-    nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, },
+    nostate1, nostate1, nostate1, nostate1, nostate1, },
  },
 };
 
 static int (*ph2exchange[][2][PHASE2ST_MAX])
 	__P((struct ph2handle *, vchar_t *)) = {
  /* error */
- { { 0 }, { 0 }, },
+ { {}, {}, },
  /* Quick mode for IKE */
  {
   { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send,
@@ -176,7 +175,7 @@
 };
 
 static u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
-
+ 
 static int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *));
 static int ph1_main __P((struct ph1handle *, vchar_t *));
 static int quick_main __P((struct ph2handle *, vchar_t *));
@@ -186,35 +185,29 @@
 static int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *));
 static int etypesw1 __P((int));
 static int etypesw2 __P((int));
-static int isakmp_ph1resend __P((struct ph1handle *));
-static int isakmp_ph2resend __P((struct ph2handle *));
-
 #ifdef ENABLE_FRAG
-static int frag_handler(struct ph1handle *,
+static int frag_handler(struct ph1handle *, 
     vchar_t *, struct sockaddr *, struct sockaddr *);
 #endif
 
 /*
  * isakmp packet handler
  */
-static int
-isakmp_handler(ctx, so_isakmp)
-        void *ctx;
+int
+isakmp_handler(so_isakmp)
 	int so_isakmp;
 {
 	struct isakmp isakmp;
 	union {
 		char		buf[sizeof (isakmp) + 4];
 		u_int32_t	non_esp[2];
-		struct		{
-				     struct udphdr udp;
+		char		lbuf[sizeof(struct udphdr) + 
 #ifdef __linux
-				     struct iphdr ip;
+				     sizeof(struct iphdr) + 
 #else
-				     struct ip ip;
+				     sizeof(struct ip) + 
 #endif
-				     char buf[sizeof(isakmp) + 4];
-				} lbuf;
+				     sizeof(isakmp) + 4];
 	} x;
 	struct sockaddr_storage remote;
 	struct sockaddr_storage local;
@@ -250,25 +243,34 @@
 
 	/* Lucent IKE in UDP encapsulation */
 	{
+		struct udphdr *udp;
 #ifdef __linux__
-		if (ntohs(x.lbuf.udp.dest) == 501) {
-			extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ihl;
+		struct iphdr *ip;
+
+		udp = (struct udphdr *)&x.lbuf[0];
+		if (ntohs(udp->dest) == 501) {
+			ip = (struct iphdr *)(x.lbuf + sizeof(*udp));
+			extralen += sizeof(*udp) + ip->ihl;
 		}
 #else
-		if (ntohs(x.lbuf.udp.uh_dport) == 501) {
-			extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ip_hl;
+		struct ip *ip;
+
+		udp = (struct udphdr *)&x.lbuf[0];
+		if (ntohs(udp->uh_dport) == 501) {
+			ip = (struct ip *)(x.lbuf + sizeof(*udp));
+			extralen += sizeof(*udp) + ip->ip_hl;
 		}
 #endif
-	}
+	}	
 
 #ifdef ENABLE_NATT
-	/* we don't know about portchange yet,
+	/* we don't know about portchange yet, 
 	   look for non-esp marker instead */
 	if (x.non_esp[0] == 0 && x.non_esp[1] != 0)
 		extralen = NON_ESP_MARKER_LEN;
 #endif
 
-	/* now we know if there is an extra non-esp
+	/* now we know if there is an extra non-esp 
 	   marker at the beginning or not */
 	memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp));
 
@@ -309,7 +311,7 @@
 		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
 			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
-				"failed to receive isakmp packet: %s\n",
+				"failed to receive isakmp packet: %s\n", 
 				strerror (errno));
 		}
 		goto end;
@@ -332,11 +334,11 @@
 			(len - extralen));
 		goto end;
 	}
-
+	
 	memcpy (buf->v, tmpbuf->v + extralen, buf->l);
 
 	len -= extralen;
-
+	
 	if (len != buf->l) {
 		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
 			"received invalid length (%d != %zu), why ?\n",
@@ -347,7 +349,7 @@
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
 	plog(LLV_DEBUG, LOCATION, NULL,
 		"%d bytes message received %s\n",
-		len, saddr2str_fromto("from %s to %s",
+		len, saddr2str_fromto("from %s to %s", 
 			(struct sockaddr *)&remote,
 			(struct sockaddr *)&local));
 	plogdump(LLV_DEBUG, buf->v, buf->l);
@@ -384,7 +386,8 @@
 		vfree(tmpbuf);
 	if (buf != NULL)
 		vfree(buf);
-	return error;
+
+	return(error);
 }
 
 /*
@@ -468,8 +471,8 @@
 		/* Floating ports for NAT-T */
 		if (NATT_AVAILABLE(iph1) &&
 		    ! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
-		    ((cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) ||
-		     (cmpsaddr(iph1->local, local) != CMPSADDR_MATCH)))
+		    ((cmpsaddrstrict(iph1->remote, remote) != 0) ||
+		    (cmpsaddrstrict(iph1->local, local) != 0)))
 		{
 			/* prevent memory leak */
 			racoon_free(iph1->remote);
@@ -496,12 +499,12 @@
 			}
 
 			/* set the flag to prevent further port floating
-			   (FIXME: should we allow it? E.g. when the NAT gw
+			   (FIXME: should we allow it? E.g. when the NAT gw 
 			    is rebooted?) */
 			iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
-
+			
 			/* print some neat info */
-			plog (LLV_INFO, LOCATION, NULL,
+			plog (LLV_INFO, LOCATION, NULL, 
 			      "NAT-T: ports changed to: %s\n",
 			      saddr2str_fromto ("%s<->%s", iph1->remote, iph1->local));
 
@@ -510,7 +513,7 @@
 #endif
 
 		/* must be same addresses in one stream of a phase at least. */
-		if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) {
+		if (cmpsaddrstrict(iph1->remote, remote) != 0) {
 			char *saddr_db, *saddr_act;
 
 			saddr_db = racoon_strdup(saddr2str(iph1->remote));
@@ -636,7 +639,7 @@
 					"exchange received.\n");
 				return -1;
 			}
-			if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) {
+			if (cmpsaddrstrict(iph1->remote, remote) != 0) {
 				plog(LLV_WARNING, LOCATION, remote,
 					"remote address mismatched. "
 					"db=%s\n",
@@ -668,7 +671,7 @@
 			return -1;
 		}
 #ifdef ENABLE_HYBRID
-		/* Reinit the IVM if it's still there */
+		/* Reinit the IVM if it's still there */		
 		if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
 			oakley_delivm(iph1->mode_cfg->ivm);
 			iph1->mode_cfg->ivm = NULL;
@@ -680,8 +683,7 @@
 #endif
 
 		/* check status of phase 1 whether negotiated or not. */
-		if (iph1->status != PHASE1ST_ESTABLISHED &&
-		    iph1->status != PHASE1ST_DYING) {
+		if (iph1->status != PHASE1ST_ESTABLISHED) {
 			plog(LLV_ERROR, LOCATION, remote,
 				"can't start the quick mode, "
 				"there is no valid ISAKMP-SA, %s\n",
@@ -713,6 +715,7 @@
 		if (quick_main(iph2, msg) < 0) {
 			plog(LLV_ERROR, LOCATION, iph1->remote,
 				"phase2 negotiation failed.\n");
+			unbindph12(iph2);
 			remph2(iph2);
 			delph2(iph2);
 			return -1;
@@ -753,7 +756,7 @@
 
 		isakmp_cfg_r(iph1, msg);
 		break;
-#endif
+#endif	 
 
 	case ISAKMP_ETYPE_NONE:
 	default:
@@ -780,7 +783,7 @@
 #endif
 
 	/* ignore a packet */
-	if (iph1->status >= PHASE1ST_ESTABLISHED)
+	if (iph1->status == PHASE1ST_ESTABLISHED)
 		return 0;
 
 #ifdef ENABLE_STATS
@@ -810,8 +813,7 @@
 
 		if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
 			plog(LLV_ERROR, LOCATION, iph1->remote,
-				"failed to pre-process ph1 packet (side: %d, status %d).\n",
-				iph1->side, iph1->status);
+				"failed to pre-process packet.\n");
 			return -1;
 		} else {
 			/* ignore the error and keep phase 1 handler */
@@ -823,7 +825,7 @@
 	/* free resend buffer */
 	if (iph1->sendbuf == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"no buffer found as sendbuf\n");
+			"no buffer found as sendbuf\n"); 
 		return -1;
 	}
 #endif
@@ -831,7 +833,7 @@
 	VPTRINIT(iph1->sendbuf);
 
 	/* turn off schedule */
-	sched_cancel(&iph1->scr);
+	SCHED_KILL(iph1->scr);
 
 	/* send */
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
@@ -839,8 +841,7 @@
 			[iph1->side]
 			[iph1->status])(iph1, msg) != 0) {
 		plog(LLV_ERROR, LOCATION, iph1->remote,
-			"failed to process ph1 packet (side: %d, status: %d).\n",
-			iph1->side, iph1->status);
+			"failed to process packet.\n");
 		return -1;
 	}
 
@@ -862,23 +863,12 @@
 		/* save created date. */
 		(void)time(&iph1->created);
 
-		/* migrate ph2s from dying ph1s */
-		migrate_dying_ph12(iph1);
-
 		/* add to the schedule to expire, and seve back pointer. */
-		if (ph1_rekey_enabled(iph1)) {
-			sched_schedule(&iph1->sce,
-				       iph1->approval->lifetime *
-				       PFKEY_SOFT_LIFETIME_RATE / 100,
-				       isakmp_ph1dying_stub);
-		} else {
-			sched_schedule(&iph1->sce, iph1->approval->lifetime,
-				       isakmp_ph1expire_stub);
-		}
-
+		iph1->sce = sched_new(iph1->approval->lifetime,
+		    isakmp_ph1expire_stub, iph1);
 #ifdef ENABLE_HYBRID
 		if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
-			switch (iph1->approval->authmethod) {
+			switch(AUTHMETHOD(iph1)) {
 			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
 			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
 			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
@@ -915,20 +905,18 @@
 				/* ignore */
 			}
 		}
-		if (iph1->initial_contact_received)
-			isakmp_info_recv_initialcontact(iph1, NULL);
 
 		log_ph1established(iph1);
 		plog(LLV_DEBUG, LOCATION, NULL, "===\n");
 
-		/*
+		/* 
 		 * SA up shell script hook: do it now,except if
 		 * ISAKMP mode config was requested. In the later
 		 * case it is done when we receive the configuration.
 		 */
 		if ((iph1->status == PHASE1ST_ESTABLISHED) &&
-		    !iph1->rmconf->mode_cfg) {
-			switch (iph1->approval->authmethod) {
+		    !iph1->rmconf->mode_cfg) { 
+			switch (AUTHMETHOD(iph1)) {
 #ifdef ENABLE_HYBRID
 			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
@@ -986,8 +974,7 @@
 			    [iph2->status])(iph2, msg);
 	if (error != 0) {
 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-			"failed to pre-process ph2 packet (side: %d, status %d).\n",
-			iph2->side, iph2->status);
+			"failed to pre-process packet.\n");
 		if (error == ISAKMP_INTERNAL_ERROR)
 			return 0;
 		isakmp_info_send_n1(iph2->ph1, error, NULL);
@@ -1001,13 +988,13 @@
 	/* free resend buffer */
 	if (iph2->sendbuf == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"no buffer found as sendbuf\n");
+			"no buffer found as sendbuf\n"); 
 		return -1;
 	}
 	VPTRINIT(iph2->sendbuf);
 
 	/* turn off schedule */
-	sched_cancel(&iph2->scr);
+	SCHED_KILL(iph2->scr);
 
 	/* send */
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
@@ -1015,8 +1002,7 @@
 			[iph2->side]
 			[iph2->status])(iph2, msg) != 0) {
 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-			"failed to process ph2 packet (side: %d, status: %d).\n",
-			iph2->side, iph2->status);
+			"failed to process packet.\n");
 		return -1;
 	}
 
@@ -1032,7 +1018,7 @@
 }
 
 /* new negotiation of phase 1 for initiator */
-struct ph1handle *
+int
 isakmp_ph1begin_i(rmconf, remote, local)
 	struct remoteconf *rmconf;
 	struct sockaddr *remote, *local;
@@ -1045,7 +1031,7 @@
 	/* get new entry to isakmp status table. */
 	iph1 = newph1();
 	if (iph1 == NULL)
-		return NULL;
+		return -1;
 
 	iph1->status = PHASE1ST_START;
 	iph1->rmconf = rmconf;
@@ -1060,7 +1046,7 @@
 #ifdef ENABLE_HYBRID
 	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
 		delph1(iph1);
-		return NULL;
+		return -1;
 	}
 #endif
 #ifdef ENABLE_FRAG
@@ -1076,7 +1062,7 @@
 	/* XXX copy remote address */
 	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
 		delph1(iph1);
-		return NULL;
+		return -1;
 	}
 
 	(void)insph1(iph1);
@@ -1112,7 +1098,7 @@
 		remph1(iph1);
 		delph1(iph1);
 
-		return NULL;
+		return -1;
 	}
 
 #ifdef ENABLE_STATS
@@ -1123,7 +1109,7 @@
 		timedelta(&start, &end));
 #endif
 
-	return iph1;
+	return 0;
 }
 
 /* new negotiation of phase 1 for responder */
@@ -1134,19 +1120,27 @@
 	u_int8_t etype;
 {
 	struct isakmp *isakmp = (struct isakmp *)msg->v;
+	struct remoteconf *rmconf;
 	struct ph1handle *iph1;
-	struct rmconfselector rmsel;
+	struct etypes *etypeok;
 #ifdef ENABLE_STATS
 	struct timeval start, end;
 #endif
 
-	/* check if this etype is allowed */
-	memset(&rmsel, 0, sizeof(rmsel));
-	rmsel.remote = remote;
-	if (enumrmconf(&rmsel, check_etypeok, (void *) (intptr_t) etype) == 0) {
+	/* look for my configuration */
+	rmconf = getrmconf(remote);
+	if (rmconf == NULL) {
 		plog(LLV_ERROR, LOCATION, remote,
-		     "exchange %s not allowed in any applicable rmconf.\n",
-		     s_isakmp_etype(etype));
+			"couldn't find "
+			"configuration.\n");
+		return -1;
+	}
+
+	/* check to be acceptable exchange type */
+	etypeok = check_etypeok(rmconf, etype);
+	if (etypeok == NULL) {
+		plog(LLV_ERROR, LOCATION, remote,
+			"not acceptable %s mode\n", s_isakmp_etype(etype));
 		return -1;
 	}
 
@@ -1157,9 +1151,10 @@
 
 	memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
 	iph1->status = PHASE1ST_START;
+	iph1->rmconf = rmconf;
 	iph1->flags = 0;
 	iph1->side = RESPONDER;
-	iph1->etype = etype;
+	iph1->etype = etypeok->type;
 	iph1->version = isakmp->v;
 	iph1->msgid = 0;
 #ifdef HAVE_GSSAPI
@@ -1186,9 +1181,8 @@
 		iph1->natt_flags |= (NAT_PORTS_CHANGED);
 #endif
 
-	/* copy remote address; remote and local always contain
-	 * port numbers so rmconf is not needed */
-	if (copy_ph1addresses(iph1, NULL, remote, local) < 0) {
+	/* copy remote address */
+	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
 		delph1(iph1);
 		return -1;
 	}
@@ -1224,8 +1218,7 @@
 			[iph1->side]
 			[iph1->status])(iph1, msg) < 0) {
 		plog(LLV_ERROR, LOCATION, remote,
-			"failed to process ph1 packet (side: %d, status: %d).\n",
-			iph1->side, iph1->status);
+			"failed to process packet.\n");
 		remph1(iph1);
 		delph1(iph1);
 		return -1;
@@ -1267,12 +1260,6 @@
 	}
 #endif
 
-	/* fixup ph2 ports for this ph1 */
-	if (extract_port(iph2->src) == 0)
-		set_port(iph2->src, extract_port(iph1->local));
-	if (extract_port(iph2->dst) == 0)
-		set_port(iph2->dst, extract_port(iph1->remote));
-
 	/* found ISAKMP-SA. */
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
 	plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
@@ -1290,13 +1277,14 @@
 #ifdef ENABLE_STATS
 	gettimeofday(&iph2->start, NULL);
 #endif
-	if (iph2->status != PHASE2ST_EXPIRED) /* Phase 1 is already bound (ongoing rekeying) */
-		bindph12(iph1, iph2);
+	/* found isakmp-sa */
+	bindph12(iph1, iph2);
 	iph2->status = PHASE2ST_STATUS2;
 
 	if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
 			 [iph2->side]
 			 [iph2->status])(iph2, NULL) < 0) {
+		unbindph12(iph2);
 		/* release ipsecsa handler due to internal error. */
 		remph2(iph2);
 		return -1;
@@ -1331,6 +1319,7 @@
 		return -1;
 	}
 
+	iph2->ph1 = iph1;
 	iph2->side = RESPONDER;
 	iph2->status = PHASE2ST_START;
 	iph2->flags = isakmp->flags;
@@ -1351,6 +1340,15 @@
 		delph2(iph2);
 		return -1;
 	}
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
+	if (set_port(iph2->dst, 0) == NULL ||
+	    set_port(iph2->src, 0) == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		     "invalid family: %d\n", iph2->dst->sa_family);
+		delph2(iph2);
+		return -1;
+	}
+#endif
 
 	/* add new entry to isakmp status table */
 	insph2(iph2);
@@ -1378,14 +1376,14 @@
 	                   [iph2->status])(iph2, msg);
 	if (error != 0) {
 		plog(LLV_ERROR, LOCATION, iph1->remote,
-			"failed to pre-process ph2 packet (side: %d, status: %d).\n",
-			iph2->side, iph2->status);
+			"failed to pre-process packet.\n");
 		if (error != ISAKMP_INTERNAL_ERROR)
 			isakmp_info_send_n1(iph2->ph1, error, NULL);
 		/*
 		 * release handler because it's wrong that ph2handle is kept
 		 * after failed to check message for responder's.
 		 */
+		unbindph12(iph2);
 		remph2(iph2);
 		delph2(iph2);
 		return -1;
@@ -1397,8 +1395,7 @@
 			[iph2->side]
 			[iph2->status])(iph2, msg) < 0) {
 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-			"failed to process ph2 packet (side: %d, status: %d).\n",
-			iph2->side, iph2->status);
+			"failed to process packet.\n");
 		/* don't release handler */
 		return -1;
 	}
@@ -1529,7 +1526,14 @@
 	initctdtree();
 	init_recvdpkt();
 
-	return 0;
+	if (isakmp_open() < 0)
+		goto err;
+
+	return(0);
+
+err:
+	isakmp_close();
+	return(-1);
 }
 
 /*
@@ -1568,172 +1572,211 @@
 
 /* open ISAKMP sockets. */
 int
-isakmp_open(struct sockaddr *addr, int udp_encap)
+isakmp_open()
 {
 	const int yes = 1;
-	int ifnum = 0, encap_ifnum = 0, fd;
-	struct sockaddr_in *sin = (struct sockaddr_in *) addr;
+	int ifnum = 0, encap_ifnum = 0;
 #ifdef INET6
-	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr;
 	int pktinfo;
 #endif
-#ifdef ENABLE_NATT
-	int option = -1;
-#endif
+	struct myaddrs *p;
 
-	/* warn if wildcard address - should we forbid this? */
-	switch (addr->sa_family) {
-	case AF_INET:
-		if (sin->sin_addr.s_addr == 0)
-			plog(LLV_WARNING, LOCATION, NULL,
-			     "listening to wildcard address,"
-			     "broadcast IKE packet may kill you\n");
-		break;
-#ifdef INET6
-	case AF_INET6:
-		if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-			     "ignoring multicast address %s\n",
-			     saddr2str(addr));
-			return -1;
-		}
+	for (p = lcconf->myaddrs; p; p = p->next) {
+		if (!p->addr)
+			continue;
 
-		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
-			plog(LLV_WARNING, LOCATION, NULL,
-			     "listening to wildcard address, "
-			     "broadcast IKE packet may kill you\n");
-		break;
-#endif
-	default:
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unsupported address family %d\n",
-		     addr->sa_family);
-		return -1;
-	}
-
-	if ((fd = privsep_socket(addr->sa_family, SOCK_DGRAM, 0)) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "socket(%s)\n", strerror(errno));
-		return -1;
-	}
-	close_on_exec(fd);
-	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "failed to put socket in non-blocking mode\n");
-
-	/* receive my interface address on inbound packets. */
-	switch (addr->sa_family) {
-	case AF_INET:
-		if (setsockopt(fd, IPPROTO_IP,
-#ifdef __linux__
-			       IP_PKTINFO,
-#else
-			       IP_RECVDSTADDR,
-#endif
-			       (const void *) &yes, sizeof(yes)) < 0) {
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "setsockopt IP_RECVDSTADDR (%s)\n",
-			     strerror(errno));
-			goto err;
-		}
-
-#ifdef ENABLE_NATT
-		if (udp_encap)
-			option = UDP_ENCAP_ESPINUDP;
-#if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01)
-		else
-			option = UDP_ENCAP_ESPINUDP_NON_IKE;
-#endif
-		if (option == -1)
+		/* warn if wildcard address - should we forbid this? */
+		switch (p->addr->sa_family) {
+		case AF_INET:
+			if (((struct sockaddr_in *)p->addr)->sin_addr.s_addr == 0)
+				plog(LLV_WARNING, LOCATION, NULL,
+					"listening to wildcard address,"
+					"broadcast IKE packet may kill you\n");
 			break;
-
-		if (setsockopt(fd, SOL_UDP,
-			       UDP_ENCAP, &option,
-			       sizeof(option)) < 0) {
-			plog(LLV_WARNING, LOCATION, NULL,
-			     "setsockopt(%s): UDP_ENCAP %s\n",
-			     option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
-			     strerror(errno));
-		} else {
-			plog(LLV_INFO, LOCATION, NULL,
-			     "%s used for NAT-T\n",
-			     saddr2str(addr));
-		}
+#ifdef INET6
+		case AF_INET6:
+			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)p->addr)->sin6_addr))
+				plog(LLV_WARNING, LOCATION, NULL,
+					"listening to wildcard address, "
+					"broadcast IKE packet may kill you\n");
+			break;
 #endif
-		break;
+		default:
+			plog(LLV_ERROR, LOCATION, NULL,
+				"unsupported address family %d\n",
+				lcconf->default_af);
+			goto err_and_next;
+		}
 
 #ifdef INET6
-	case AF_INET6:
-#if defined(INET6_ADVAPI)
+		if (p->addr->sa_family == AF_INET6 &&
+		    IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)
+					    p->addr)->sin6_addr))
+		{
+			plog(LLV_DEBUG, LOCATION, NULL, 
+				"Ignoring multicast address %s\n",
+				saddr2str(p->addr));
+				racoon_free(p->addr);
+				p->addr = NULL;
+			continue;
+		}
+#endif
+
+		if ((p->sock = socket(p->addr->sa_family, SOCK_DGRAM, 0)) < 0) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"socket (%s)\n", strerror(errno));
+			goto err_and_next;
+		}
+
+		if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
+			plog(LLV_WARNING, LOCATION, NULL,
+				"failed to put socket in non-blocking mode\n");
+
+		/* receive my interface address on inbound packets. */
+		switch (p->addr->sa_family) {
+		case AF_INET:
+			if (setsockopt(p->sock, IPPROTO_IP,
+#ifdef __linux__
+				       IP_PKTINFO,
+#else
+				       IP_RECVDSTADDR,
+#endif
+					(const void *)&yes, sizeof(yes)) < 0) {
+				plog(LLV_ERROR, LOCATION, NULL,
+					"setsockopt IP_RECVDSTADDR (%s)\n", 
+					strerror(errno));
+				goto err_and_next;
+			}
+			break;
+#ifdef INET6
+		case AF_INET6:
+#ifdef INET6_ADVAPI
 #ifdef IPV6_RECVPKTINFO
-		pktinfo = IPV6_RECVPKTINFO;
+			pktinfo = IPV6_RECVPKTINFO;
 #else  /* old adv. API */
-		pktinfo = IPV6_PKTINFO;
+			pktinfo = IPV6_PKTINFO;
 #endif /* IPV6_RECVPKTINFO */
 #else
-		pktinfo = IPV6_RECVDSTADDR;
+			pktinfo = IPV6_RECVDSTADDR;
 #endif
-		if (setsockopt(fd, IPPROTO_IPV6, pktinfo,
-			       (const void *) &yes, sizeof(yes)) < 0) {
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "setsockopt IPV6_RECVDSTADDR (%d):%s\n",
-			     pktinfo, strerror(errno));
-			goto err;
+			if (setsockopt(p->sock, IPPROTO_IPV6, pktinfo,
+					(const void *)&yes, sizeof(yes)) < 0)
+			{
+				plog(LLV_ERROR, LOCATION, NULL,
+					"setsockopt IPV6_RECVDSTADDR (%d):%s\n",
+					pktinfo, strerror(errno));
+				goto err_and_next;
+			}
+			break;
+#endif
 		}
 
 #ifdef IPV6_USE_MIN_MTU
-		if (setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
-			       (void *) &yes, sizeof(yes)) < 0) {
+		if (p->addr->sa_family == AF_INET6 &&
+		    setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+		    (void *)&yes, sizeof(yes)) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			     "setsockopt IPV6_USE_MIN_MTU (%s)\n",
-			     strerror(errno));
-			goto err;
+			    "setsockopt IPV6_USE_MIN_MTU (%s)\n", 
+			    strerror(errno));
+			return -1;
 		}
 #endif
-		break;
+
+		if (setsockopt_bypass(p->sock, p->addr->sa_family) < 0)
+			goto err_and_next;
+
+		if (bind(p->sock, p->addr, sysdep_sa_len(p->addr)) < 0) {
+			plog(LLV_ERROR, LOCATION, p->addr,
+				"failed to bind to address %s (%s).\n",
+				saddr2str(p->addr), strerror(errno));
+			close(p->sock);
+			goto err_and_next;
+		}
+
+		ifnum++;
+
+		plog(LLV_INFO, LOCATION, NULL,
+			"%s used as isakmp port (fd=%d)\n",
+			saddr2str(p->addr), p->sock);
+
+#ifdef ENABLE_NATT
+		if (p->addr->sa_family == AF_INET) {
+			int option = -1;
+
+
+			if(p->udp_encap)
+				option = UDP_ENCAP_ESPINUDP;
+#if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01)
+			else
+				option = UDP_ENCAP_ESPINUDP_NON_IKE;
 #endif
+			if(option != -1){
+				if (setsockopt (p->sock, SOL_UDP, 
+				    UDP_ENCAP, &option, sizeof (option)) < 0) {
+					plog(LLV_WARNING, LOCATION, NULL,
+					    "setsockopt(%s): UDP_ENCAP %s\n",
+					    option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
+						 strerror(errno));
+					goto skip_encap;
+				}
+				else {
+					plog(LLV_INFO, LOCATION, NULL,
+						 "%s used for NAT-T\n",
+						 saddr2str(p->addr));
+					encap_ifnum++;
+				}
+			}
+		}
+skip_encap:
+#endif
+		continue;
+
+	err_and_next:
+		racoon_free(p->addr);
+		p->addr = NULL;
+		if (! lcconf->autograbaddr && lcconf->strict_address)
+			return -1;
+		continue;
 	}
 
-	if (setsockopt(fd, SOL_SOCKET,
-#ifdef __linux__
-		       SO_REUSEADDR,
-#else
-		       SO_REUSEPORT,
-#endif
-		       (void *) &yes, sizeof(yes)) < 0) {
+	if (!ifnum) {
 		plog(LLV_ERROR, LOCATION, NULL,
-		     "failed to set REUSE flag on %s (%s).\n",
-		     saddr2str(addr), strerror(errno));
-		goto err;
+			"no address could be bound.\n");
+		return -1;
 	}
 
-	if (setsockopt_bypass(fd, addr->sa_family) < 0)
-		goto err;
-
-	if (privsep_bind(fd, addr, sysdep_sa_len(addr)) < 0) {
-		plog(LLV_ERROR, LOCATION, addr,
-		     "failed to bind to address %s (%s).\n",
-		     saddr2str(addr), strerror(errno));
-		goto err;
+#ifdef ENABLE_NATT
+	if (natt_enabled_in_rmconf() && !encap_ifnum) {
+		plog(LLV_WARNING, LOCATION, NULL, 
+			"NAT-T is enabled in at least one remote{} section,\n");
+		plog(LLV_WARNING, LOCATION, NULL, 
+			"but no 'isakmp_natt' address was specified!\n");
 	}
+#endif
 
-	plog(LLV_INFO, LOCATION, NULL,
-	     "%s used as isakmp port (fd=%d)\n",
-	     saddr2str(addr), fd);
-
-	monitor_fd(fd, isakmp_handler, NULL, 1);
-	return fd;
-
-err:
-	close(fd);
-	return -1;
+	return 0;
 }
 
 void
-isakmp_close(int fd)
+isakmp_close()
 {
-	unmonitor_fd(fd);
-	close(fd);
+#ifndef ANDROID_PATCHED
+	struct myaddrs *p, *next;
+
+	for (p = lcconf->myaddrs; p; p = next) {
+		next = p->next;
+
+		if (!p->addr) {
+			racoon_free(p);
+			continue;
+		}
+		close(p->sock);
+		racoon_free(p->addr);
+		racoon_free(p);
+	}
+
+	lcconf->myaddrs = NULL;
+#endif
 }
 
 int
@@ -1755,23 +1798,23 @@
 		extralen = 0;
 
 #ifdef ENABLE_FRAG
-	/*
+	/* 
 	 * Do not add the non ESP marker for a packet that will
-	 * be fragmented. The non ESP marker should appear in
+	 * be fragmented. The non ESP marker should appear in 
 	 * all fragment's packets, but not in the fragmented packet
 	 */
-	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN)
+	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) 
 		extralen = 0;
 #endif
 	if (extralen)
 		plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
 
-	/* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
-	   must added just before the packet itself. For this we must
+	/* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker) 
+	   must added just before the packet itself. For this we must 
 	   allocate a new buffer and release it at the end. */
 	if (extralen) {
 		if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
+			plog(LLV_ERROR, LOCATION, NULL, 
 			    "vbuf allocation failed\n");
 			return -1;
 		}
@@ -1788,21 +1831,22 @@
 #endif
 
 	/* select the socket to be sent */
-	s = myaddr_getfd(iph1->local);
-	if (s == -1)
+	s = getsockmyaddr(iph1->local);
+	if (s == -1){
 		return -1;
+	}
 
-	plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l,
+	plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l, 
 	      saddr2str_fromto("from %s to %s", iph1->local, iph1->remote));
 
 #ifdef ENABLE_FRAG
 	if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) {
 		if (isakmp_sendfrags(iph1, sbuf) == -1) {
-			plog(LLV_ERROR, LOCATION, NULL,
+			plog(LLV_ERROR, LOCATION, NULL, 
 			    "isakmp_sendfrags failed\n");
 			return -1;
 		}
-	} else
+	} else 
 #endif
 	{
 		len = sendfromto(s, sbuf->v, sbuf->l,
@@ -1813,24 +1857,32 @@
 			return -1;
 		}
 	}
-
+	
 	return 0;
 }
 
 /* called from scheduler */
-static void
+void
 isakmp_ph1resend_stub(p)
-	struct sched *p;
+	void *p;
 {
-	struct ph1handle *iph1 = container_of(p, struct ph1handle, scr);
+	struct ph1handle *iph1;
 
-	if (isakmp_ph1resend(iph1) < 0) {
+	iph1=(struct ph1handle *)p;
+	if(isakmp_ph1resend(iph1) < 0){
+		if(iph1->scr != NULL){
+			/* Should not happen...
+			 */
+			sched_kill(iph1->scr);
+			iph1->scr=NULL;
+		}
+
 		remph1(iph1);
 		delph1(iph1);
 	}
 }
 
-static int
+int
 isakmp_ph1resend(iph1)
 	struct ph1handle *iph1;
 {
@@ -1840,9 +1892,8 @@
 		plog(LLV_ERROR, LOCATION, NULL,
 			"phase1 negotiation failed due to time up. %s\n",
 			isakmp_pindex(&iph1->index, iph1->msgid));
-		/* XXX is the peer really "dead" here ??? */
-		script_hook(iph1, SCRIPT_PHASE1_DEAD);
-		evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, 
+		    EVTT_PEER_NO_RESPONSE, NULL);
 
 		return -1;
 	}
@@ -1851,7 +1902,8 @@
 		plog(LLV_ERROR, LOCATION, NULL,
 			 "phase1 negotiation failed due to send error. %s\n",
 			 isakmp_pindex(&iph1->index, iph1->msgid));
-		evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, 
+				 EVTT_PEER_NO_RESPONSE, NULL);
 		return -1;
 	}
 
@@ -1861,40 +1913,35 @@
 
 	iph1->retry_counter--;
 
-	sched_schedule(&iph1->scr, lcconf->retry_interval,
-		       isakmp_ph1resend_stub);
+	iph1->scr = sched_new(iph1->rmconf->retry_interval,
+		isakmp_ph1resend_stub, iph1);
 
 	return 0;
 }
 
-int
-isakmp_ph1send(iph1)
-	struct ph1handle *iph1;
-{
-	iph1->retry_counter = lcconf->retry_counter;
-	return isakmp_ph1resend(iph1);
-}
-
 /* called from scheduler */
-static void
+void
 isakmp_ph2resend_stub(p)
-	struct sched *p;
+	void *p;
 {
-	struct ph2handle *iph2 = container_of(p, struct ph2handle, scr);
+	struct ph2handle *iph2;
 
-	if (isakmp_ph2resend(iph2) < 0) {
+	iph2=(struct ph2handle *)p;
+
+	if(isakmp_ph2resend(iph2) < 0){
+		unbindph12(iph2);
 		remph2(iph2);
 		delph2(iph2);
 	}
 }
 
-static int
+int
 isakmp_ph2resend(iph2)
 	struct ph2handle *iph2;
 {
 	/* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function
 	 */
-	if (iph2->ph1->status >= PHASE1ST_EXPIRED) {
+	if (iph2->ph1->status == PHASE1ST_EXPIRED){
 		plog(LLV_ERROR, LOCATION, NULL,
 			"phase2 negotiation failed due to phase1 expired. %s\n",
 				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
@@ -1905,7 +1952,7 @@
 		plog(LLV_ERROR, LOCATION, NULL,
 			"phase2 negotiation failed due to time up. %s\n",
 				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
-		evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL);
+		EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
 		unbindph12(iph2);
 		return -1;
 	}
@@ -1914,7 +1961,8 @@
 		plog(LLV_ERROR, LOCATION, NULL,
 			"phase2 negotiation failed due to send error. %s\n",
 				isakmp_pindex(&iph2->ph1->index, iph2->msgid));
-		evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL);
+		EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
+
 		return -1;
 	}
 
@@ -1924,77 +1972,19 @@
 
 	iph2->retry_counter--;
 
-	sched_schedule(&iph2->scr, lcconf->retry_interval,
-		       isakmp_ph2resend_stub);
+	iph2->scr = sched_new(iph2->ph1->rmconf->retry_interval,
+		isakmp_ph2resend_stub, iph2);
 
 	return 0;
 }
 
-int
-isakmp_ph2send(iph2)
-	struct ph2handle *iph2;
-{
-	iph2->retry_counter = lcconf->retry_counter;
-	return isakmp_ph2resend(iph2);
-}
-
-/* called from scheduler */
-void
-isakmp_ph1dying_stub(p)
-	struct sched *p;
-{
-
-	isakmp_ph1dying(container_of(p, struct ph1handle, sce));
-}
-
-void
-isakmp_ph1dying(iph1)
-	struct ph1handle *iph1;
-{
-	struct ph1handle *new_iph1;
-	struct ph2handle *p;
-	struct remoteconf *rmconf;
-
-	if (iph1->status >= PHASE1ST_DYING)
-		return;
-
-	/* Going away in after a while... */
-	iph1->status = PHASE1ST_DYING;
-
-	/* Any fresh phase1s? */
-	new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1);
-	if (new_iph1 == NULL) {
-		LIST_FOREACH(p, &iph1->ph2tree, ph1bind) {
-			if (p->status != PHASE2ST_ESTABLISHED)
-				continue;
-
-			plog(LLV_INFO, LOCATION, NULL,
-			     "renegotiating phase1 to %s due to "
-			     "active phase2\n",
-			     saddrwop2str(iph1->remote));
-
-			if (iph1->side == INITIATOR)
-				isakmp_ph1begin_i(iph1->rmconf, iph1->remote,
-						  iph1->local);
-
-			break;
-		}
-	} else {
-		migrate_ph12(iph1, new_iph1);
-	}
-
-	/* Schedule for expiration */
-	sched_schedule(&iph1->sce, iph1->approval->lifetime *
-		       (100 - PFKEY_SOFT_LIFETIME_RATE) / 100,
-		       isakmp_ph1expire_stub);
-}
-
 /* called from scheduler */
 void
 isakmp_ph1expire_stub(p)
-	struct sched *p;
+	void *p;
 {
-	isakmp_ph1expire(container_of(p, struct ph1handle, sce));
+
+	isakmp_ph1expire((struct ph1handle *)p);
 }
 
 void
@@ -2003,7 +1993,9 @@
 {
 	char *src, *dst;
 
-	if (iph1->status < PHASE1ST_EXPIRED) {
+	SCHED_KILL(iph1->sce);
+
+	if(iph1->status != PHASE1ST_EXPIRED){
 		src = racoon_strdup(saddr2str(iph1->local));
 		dst = racoon_strdup(saddr2str(iph1->remote));
 		STRDUP_FATAL(src);
@@ -2018,44 +2010,41 @@
 		iph1->status = PHASE1ST_EXPIRED;
 	}
 
-	isakmp_ph1delete(iph1);
+	/*
+	 * the phase1 deletion is postponed until there is no phase2.
+	 */
+	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
+		iph1->sce = sched_new(1, isakmp_ph1expire_stub, iph1);
+		return;
+	}
+
+	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 }
 
 /* called from scheduler */
 void
 isakmp_ph1delete_stub(p)
-	struct sched *p;
+	void *p;
 {
 
-	isakmp_ph1delete(container_of(p, struct ph1handle, sce));
+	isakmp_ph1delete((struct ph1handle *)p);
 }
 
 void
 isakmp_ph1delete(iph1)
 	struct ph1handle *iph1;
 {
-	struct ph2handle *p, *next;
-	struct ph1handle *new_iph1;
 	char *src, *dst;
 
-	/* Migrate established phase2s. Any fresh phase1s? */
-	new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1);
-	if (new_iph1 != NULL)
-		migrate_ph12(iph1, new_iph1);
+	SCHED_KILL(iph1->sce);
 
-	/* Discard any left phase2s */
-	for (p = LIST_FIRST(&iph1->ph2tree); p; p = next) {
-		next = LIST_NEXT(p, ph1bind);
-		if (p->status == PHASE2ST_ESTABLISHED)
-			isakmp_info_send_d2(p);
-		/* remove all ph2 handles,
-		 * as ph1handle will be expired soon
-		 */
-		delete_spd(p, 1);
-		remph2(p);
-		delph2(p);
+	if (LIST_FIRST(&iph1->ph2tree) != NULL) {
+		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
+		return;
 	}
 
+	/* don't re-negosiation when the phase 1 SA expires. */
+
 	src = racoon_strdup(saddr2str(iph1->local));
 	dst = racoon_strdup(saddr2str(iph1->remote));
 	STRDUP_FATAL(src);
@@ -2064,16 +2053,14 @@
 	plog(LLV_INFO, LOCATION, NULL,
 		"ISAKMP-SA deleted %s-%s spi:%s\n",
 		src, dst, isakmp_pindex(&iph1->index, 0));
-
-	evt_phase1(iph1, EVT_PHASE1_DOWN, NULL);
-	if (new_iph1 == NULL && ph1_rekey_enabled(iph1))
-		script_hook(iph1, SCRIPT_PHASE1_DEAD);
-
+	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
 	racoon_free(src);
 	racoon_free(dst);
 
 	remph1(iph1);
 	delph1(iph1);
+
+	return;
 }
 
 /* called from scheduler.
@@ -2084,10 +2071,10 @@
  */
 void
 isakmp_ph2expire_stub(p)
-	struct sched *p;
+	void *p;
 {
 
-	isakmp_ph2expire(container_of(p, struct ph2handle, sce));
+	isakmp_ph2expire((struct ph2handle *)p);
 }
 
 void
@@ -2096,6 +2083,8 @@
 {
 	char *src, *dst;
 
+	SCHED_KILL(iph2->sce);
+
 	src = racoon_strdup(saddrwop2str(iph2->src));
 	dst = racoon_strdup(saddrwop2str(iph2->dst));
 	STRDUP_FATAL(src);
@@ -2107,16 +2096,19 @@
 	racoon_free(dst);
 
 	iph2->status = PHASE2ST_EXPIRED;
-	sched_schedule(&iph2->sce, 1, isakmp_ph2delete_stub);
+
+	iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
+
+	return;
 }
 
 /* called from scheduler */
 void
 isakmp_ph2delete_stub(p)
-	struct sched *p;
+	void *p;
 {
 
-	isakmp_ph2delete(container_of(p, struct ph2handle, sce));
+	isakmp_ph2delete((struct ph2handle *)p);
 }
 
 void
@@ -2125,6 +2117,8 @@
 {
 	char *src, *dst;
 
+	SCHED_KILL(iph2->sce);
+
 	src = racoon_strdup(saddrwop2str(iph2->src));
 	dst = racoon_strdup(saddrwop2str(iph2->dst));
 	STRDUP_FATAL(src);
@@ -2135,6 +2129,7 @@
 	racoon_free(src);
 	racoon_free(dst);
 
+	unbindph12(iph2);
 	remph2(iph2);
 	delph2(iph2);
 
@@ -2149,39 +2144,25 @@
  * if phase1 has been finished, begin phase2.
  */
 int
-isakmp_post_acquire(iph2, iph1hint, nopassive)
+isakmp_post_acquire(iph2)
 	struct ph2handle *iph2;
-	struct ph1handle *iph1hint;
-	int nopassive;
 {
 	struct remoteconf *rmconf;
 	struct ph1handle *iph1 = NULL;
-
+	
 	plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n");
 
-	/* Search appropriate configuration with masking port. Note that
-	 * we always use iph2->dst, and not iph2->sa_dst.
-	 *
-	 * XXX One possible need for using iph2->sa_dst if not NULL would
-	 * be for selecting a remote configuration based on a stable
-	 * address of a mobile node (not a CoA provided by MIGRATE/KMADDRESS
-	 * as iph2->dst hint). This scenario would require additional changes,
-	 * so no need to bother yet. --arno */
-
-	if (iph1hint == NULL || iph1hint->rmconf == NULL) {
-		rmconf = getrmconf(iph2->dst, nopassive ? GETRMCONF_F_NO_PASSIVE : 0);
-		if (rmconf == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"no configuration found for %s.\n",
-				saddrwop2str(iph2->dst));
-			return -1;
-		}
-	} else {
-		rmconf = iph1hint->rmconf;
+	/* search appropreate configuration with masking port. */
+	rmconf = getrmconf(iph2->dst);
+	if (rmconf == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"no configuration found for %s.\n",
+			saddrwop2str(iph2->dst));
+		return -1;
 	}
 
 	/* if passive mode, ignore the acquire message */
-	if (nopassive && rmconf->passive) {
+	if (rmconf->passive) {
 		plog(LLV_DEBUG, LOCATION, NULL,
 			"because of passive mode, "
 			"ignore the acquire message for %s.\n",
@@ -2189,25 +2170,38 @@
 		return 0;
 	}
 
-	/*
-	 * XXX Searching by IP addresses + ports might fail on
-	 * some cases, we should use the ISAKMP identity to search
-	 * matching ISAKMP.
+	/* 
+	 * Search isakmp status table by address and port 
+	 * If NAT-T is in use, consider null ports as a 
+	 * wildcard and use IKE ports instead.
 	 */
-	iph1 = getph1(iph1hint, iph2->src, iph2->dst, 0);
+#ifdef ENABLE_NATT
+	if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
+		if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) {
+			set_port(iph2->src, extract_port(iph1->local));
+			set_port(iph2->dst, extract_port(iph1->remote));
+		}
+	} else {
+		iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
+	}
+#else
+	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
+#endif
 
 	/* no ISAKMP-SA found. */
 	if (iph1 == NULL) {
+		struct sched *sc;
+
 		iph2->retry_checkph1 = lcconf->retry_checkph1;
-		sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
+		sc = sched_new(1, isakmp_chkph1there_stub, iph2);
 		plog(LLV_INFO, LOCATION, NULL,
 			"IPsec-SA request for %s queued "
 			"due to no phase1 found.\n",
 			saddrwop2str(iph2->dst));
 
 		/* start phase 1 negotiation as a initiator. */
-		if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) == NULL) {
-			sched_cancel(&iph2->sce);
+		if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) < 0) {
+			SCHED_KILL(sc);
 			return -1;
 		}
 
@@ -2216,9 +2210,9 @@
 	}
 
 	/* found ISAKMP-SA, but on negotiation. */
-	if (iph1->status < PHASE1ST_ESTABLISHED) {
+	if (iph1->status != PHASE1ST_ESTABLISHED) {
 		iph2->retry_checkph1 = lcconf->retry_checkph1;
-		sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
+		sched_new(1, isakmp_chkph1there_stub, iph2);
 		plog(LLV_INFO, LOCATION, iph2->dst,
 			"request for establishing IPsec-SA was queued "
 			"due to no phase1 found.\n");
@@ -2239,69 +2233,6 @@
 	return 0;
 }
 
-int
-isakmp_get_sainfo(iph2, sp_out, sp_in)
-	struct ph2handle *iph2;
-	struct secpolicy *sp_out, *sp_in;
-{
-	struct remoteconf *conf;
-	uint32_t remoteid = 0;
-
-	plog(LLV_DEBUG, LOCATION, NULL,
-		"new acquire %s\n", spidx2str(&sp_out->spidx));
-
-	/* get sainfo */
-	{
-		vchar_t *idsrc, *iddst;
-
-		idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src,
-			sp_out->spidx.prefs, sp_out->spidx.ul_proto);
-		if (idsrc == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"failed to get ID for %s\n",
-				spidx2str(&sp_out->spidx));
-			return -1;
-		}
-		iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst,
-			sp_out->spidx.prefd, sp_out->spidx.ul_proto);
-		if (iddst == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"failed to get ID for %s\n",
-				spidx2str(&sp_out->spidx));
-			vfree(idsrc);
-			return -1;
-		}
-
-		conf = getrmconf(iph2->dst, 0);
-		if (conf != NULL)
-			remoteid = conf->ph1id;
-		else
-			plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n");
-
-		iph2->sainfo = getsainfo(idsrc, iddst, NULL, NULL, remoteid);
-		vfree(idsrc);
-		vfree(iddst);
-		if (iph2->sainfo == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"failed to get sainfo.\n");
-			return -1;
-			/* XXX should use the algorithm list from register message */
-		}
-
-		plog(LLV_DEBUG, LOCATION, NULL,
-			"selected sainfo: %s\n", sainfo2str(iph2->sainfo));
-	}
-
-	if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-			"failed to create saprop.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-
 /*
  * receive GETSPI from kernel.
  */
@@ -2314,7 +2245,7 @@
 #endif
 
 	/* don't process it because there is no suitable phase1-sa. */
-	if (iph2->ph1->status >= PHASE1ST_EXPIRED) {
+	if (iph2->ph1->status == PHASE1ST_EXPIRED) {
 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
 			"the negotiation is stopped, "
 			"because there is no suitable ISAKMP-SA.\n");
@@ -2342,9 +2273,9 @@
 /* called by scheduler */
 void
 isakmp_chkph1there_stub(p)
-	struct sched *p;
+	void *p;
 {
-	isakmp_chkph1there(container_of(p, struct ph2handle, sce));
+	isakmp_chkph1there((struct ph2handle *)p);
 }
 
 void
@@ -2366,14 +2297,33 @@
 		/* send acquire to kernel as error */
 		pk_sendeacquire(iph2);
 
+		unbindph12(iph2);
 		remph2(iph2);
 		delph2(iph2);
 
 		return;
 	}
 
-	/* Search isakmp status table by address and port */
+	/* 
+	 * Search isakmp status table by address and port 
+	 * If NAT-T is in use, consider null ports as a 
+	 * wildcard and use IKE ports instead.
+	 */
+#ifdef ENABLE_NATT
+	if (!extract_port(iph2->src) && !extract_port(iph2->dst)) {
+		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: extract_port.\n");
+		if( (iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL){
+			plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found a ph1 wop.\n");
+		}
+	} else {
+		plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: searching byaddr.\n");
+		iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
+		if(iph1 != NULL)
+			plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found byaddr.\n");
+	}
+#else
 	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
+#endif
 
 	/* XXX Even if ph1 as responder is there, should we not start
 	 * phase 2 negotiation ? */
@@ -2401,7 +2351,7 @@
 	plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
 
 	/* no isakmp-sa found */
-	sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
+	sched_new(1, isakmp_chkph1there_stub, iph2);
 
 	return;
 }
@@ -2924,9 +2874,7 @@
 	 * respect content of "remote".
 	 */
 	if (extract_port(iph1->remote) == 0) {
-		port = 0;
-		if (rmconf != NULL)
-			port = extract_port(rmconf->remote);
+		port = extract_port(rmconf->remote);
 		if (port == 0)
 			port = PORT_ISAKMP;
 		set_port(iph1->remote, port);
@@ -2939,12 +2887,8 @@
 	if (iph1->local == NULL)
 		return -1;
 
-	if (extract_port(iph1->local) == 0) {
-		port = myaddr_getsport(iph1->local);
-		if (port == 0)
-			port = PORT_ISAKMP;
+	if (extract_port(iph1->local) == 0)
 		set_port(iph1->local, PORT_ISAKMP);
-	}
 
 #ifdef ENABLE_NATT
 	if (extract_port(iph1->local) == lcconf->port_isakmp_natt) {
@@ -2991,10 +2935,10 @@
 		"ISAKMP-SA established %s-%s spi:%s\n",
 		src, dst,
 		isakmp_pindex(&iph1->index, 0));
-
-	evt_phase1(iph1, EVT_PHASE1_UP, NULL);
+	
+	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
 	if(!iph1->rmconf->mode_cfg)
-		evt_phase1(iph1, EVT_PHASE1_MODE_CFG, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
 
 	racoon_free(src);
 	racoon_free(dst);
@@ -3003,8 +2947,7 @@
 }
 
 struct payload_list *
-isakmp_plist_append_full (struct payload_list *plist, vchar_t *payload,
-			  u_int8_t payload_type, u_int8_t free_payload)
+isakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_type)
 {
 	if (! plist) {
 		plist = racoon_malloc (sizeof (struct payload_list));
@@ -3019,12 +2962,11 @@
 	plist->next = NULL;
 	plist->payload = payload;
 	plist->payload_type = payload_type;
-	plist->free_payload = free_payload;
 
 	return plist;
 }
 
-vchar_t *
+vchar_t * 
 isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
 {
 	struct payload_list *ptr = *plist, *first;
@@ -3035,7 +2977,7 @@
 	/* Seek to the first item.  */
 	while (ptr->prev) ptr = ptr->prev;
 	first = ptr;
-
+	
 	/* Compute the whole length.  */
 	while (ptr) {
 		tlen += ptr->payload->l + sizeof (struct isakmp_gen);
@@ -3060,8 +3002,6 @@
 		p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE);
 		first = ptr;
 		ptr = ptr->next;
-		if (first->free_payload)
-			vfree(first->payload);
 		racoon_free (first);
 		/* ptr->prev = NULL; first = NULL; ... omitted.  */
 		n++;
@@ -3077,7 +3017,7 @@
 }
 
 #ifdef ENABLE_FRAG
-int
+int 
 frag_handler(iph1, msg, remote, local)
 	struct ph1handle *iph1;
 	vchar_t *msg;
@@ -3088,7 +3028,7 @@
 
 	if (isakmp_frag_extract(iph1, msg) == 1) {
 		if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
-			plog(LLV_ERROR, LOCATION, remote,
+			plog(LLV_ERROR, LOCATION, remote, 
 			    "Packet reassembly failed\n");
 			return -1;
 		}
@@ -3110,6 +3050,7 @@
 	char portstr[PORT_MAX];
 	char **envp = NULL;
 	int envc = 1;
+	struct sockaddr_in *sin;
 	char **c;
 
 	if (iph1 == NULL ||
@@ -3122,7 +3063,9 @@
 #endif
 
 	/* local address */
-	GETNAMEINFO(iph1->local, addrstr, portstr);
+	sin = (struct sockaddr_in *)iph1->local;
+	inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
+	snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
 
 	if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) {
 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n");
@@ -3136,7 +3079,9 @@
 
 	/* Peer address */
 	if (iph1->remote != NULL) {
-		GETNAMEINFO(iph1->remote, addrstr, portstr);
+		sin = (struct sockaddr_in *)iph1->remote;
+		inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
+		snprintf(portstr, PORT_MAX, "%d", ntohs(sin->sin_port));
 
 		if (script_env_append(&envp, &envc, 
 		    "REMOTE_ADDR", addrstr) != 0) {
@@ -3153,16 +3098,6 @@
 		}
 	}
 
-	/* Peer identity. */
-	if (iph1->id_p != NULL) {
-		if (script_env_append(&envp, &envc, "REMOTE_ID",
-				      ipsecdoi_id2str(iph1->id_p)) != 0) {
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "Cannot set REMOTE_ID\n");
-			goto out;
-		}
-	}
-
 	if (privsep_script_exec(iph1->rmconf->script[script]->v, 
 	    script, envp) != 0) 
 		plog(LLV_ERROR, LOCATION, NULL, 
@@ -3225,7 +3160,7 @@
 	argv[1] = script_names[name];
 	argv[2] = NULL;
 
-	switch (fork()) {
+	switch (fork()) { 
 	case 0:
 		execve(argv[0], argv, envp);
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -3240,7 +3175,7 @@
 		break;
 	default:
 		break;
-	}
+	}	
 	return 0;
 
 }
@@ -3266,7 +3201,7 @@
 	iph1->status = PHASE1ST_EXPIRED;
 
 	/* Check if we have another, still valid, phase1 SA. */
-	new_iph1 = getph1(iph1, iph1->local, iph1->remote, GETPH1_F_ESTABLISHED);
+	new_iph1 = getph1byaddr(iph1->local, iph1->remote, 1);
 
 	/*
 	 * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
@@ -3305,7 +3240,6 @@
 			msg = next;
 			continue;
 		}
-		pk_fixup_sa_addresses(mhp);
 		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
@@ -3321,10 +3255,8 @@
 		 * Select only SAs where src == local and dst == remote (outgoing)
 		 * or src == remote and dst == local (incoming).
 		 */
-		if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH ||
-		     cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) &&
-		    (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH ||
-		     cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH)) {
+		if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) &&
+			(CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) {
 			msg = next;
 			continue;
 		}
@@ -3342,7 +3274,7 @@
 					ntohl(sa->sadb_sa_spi));
 			}else{
 
-				/*
+				/* 
 				 * If we have a new ph1, do not purge IPsec-SAs binded
 				 *  to a different ISAKMP-SA
 				 */
@@ -3354,7 +3286,7 @@
 				/* If the ph2handle is established, do not purge IPsec-SA */
 				if (iph2->status == PHASE2ST_ESTABLISHED ||
 					iph2->status == PHASE2ST_EXPIRED) {
-
+					
 					plog(LLV_INFO, LOCATION, NULL,
 						 "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n",
 						 ntohl(sa->sadb_sa_spi),
@@ -3365,7 +3297,7 @@
 			}
 		}
 
-
+		
 		pfkey_send_delete(lcconf->sock_pfkey,
 				  msg->sadb_msg_satype,
 				  IPSEC_MODE_ANY,
@@ -3374,6 +3306,7 @@
 		/* delete a relative phase 2 handle. */
 		if (iph2 != NULL) {
 			delete_spd(iph2, 0);
+			unbindph12(iph2);
 			remph2(iph2);
 			delph2(iph2);
 		}
@@ -3393,10 +3326,12 @@
 		 "purged ISAKMP-SA spi=%s.\n",
 		 isakmp_pindex(&(iph1->index), iph1->msgid));
 
-	isakmp_ph1delete(iph1);
+	SCHED_KILL(iph1->sce);
+
+	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 }
 
-void
+void 
 delete_spd(iph2, created)
 	struct ph2handle *iph2;
  	u_int64_t created;
@@ -3421,23 +3356,23 @@
 	dst = iph2->dst;
 
 	plog(LLV_INFO, LOCATION, NULL,
-		 "deleting a generated policy.\n");
-
+		 "generated policy, deleting it.\n");
+		
 	memset(&spidx, 0, sizeof(spidx));
 	iph2->spidx_gen = (caddr_t )&spidx;
-
+		
 	/* make inbound policy */
 	iph2->src = dst;
 	iph2->dst = src;
 	spidx.dir = IPSEC_DIR_INBOUND;
 	spidx.ul_proto = 0;
-
-	/*
+		
+	/* 
 	 * Note: code from get_proposal_r
 	 */
-
+		
 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
-
+		
 	/*
 	 * make destination address in spidx from either ID payload
 	 * or phase 1 address into a address in spidx.
@@ -3453,48 +3388,48 @@
 									 &spidx.prefd, &spidx.ul_proto);
 		if (error)
 			goto purge;
-
+			
 #ifdef INET6
 		/*
 		 * get scopeid from the SA address.
 		 * note that the phase 1 source address is used as
-		 * a destination address to search for a inbound
+		 * a destination address to search for a inbound 
 		 * policy entry because rcoon is responder.
 		 */
 		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
-			if ((error =
+			if ((error = 
 				 setscopeid((struct sockaddr *)&spidx.dst,
 							iph2->src)) != 0)
 				goto purge;
 		}
 #endif
-
+			
 		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
 			|| _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
 			idi2type = _XIDT(iph2->id);
-
+			
 	} else {
-
+			
 		plog(LLV_DEBUG, LOCATION, NULL,
 			 "get a destination address of SP index "
 			 "from phase1 address "
 			 "due to no ID payloads found "
 			 "OR because ID type is not address.\n");
-
+			
 		/*
-		 * copy the SOURCE address of IKE into the
-		 * DESTINATION address of the key to search the
+		 * copy the SOURCE address of IKE into the 
+		 * DESTINATION address of the key to search the 
 		 * SPD because the direction of policy is inbound.
 		 */
 		memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
 		switch (spidx.dst.ss_family) {
 		case AF_INET:
-			spidx.prefd =
+			spidx.prefd = 
 				sizeof(struct in_addr) << 3;
 			break;
 #ifdef INET6
 		case AF_INET6:
-			spidx.prefd =
+			spidx.prefd = 
 				sizeof(struct in6_addr) << 3;
 			break;
 #endif
@@ -3503,8 +3438,8 @@
 			break;
 		}
 	}
-
-		/* make source address in spidx */
+					
+	/* make source address in spidx */
 	if (iph2->id_p != NULL
 		&& (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
 			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
@@ -3512,8 +3447,8 @@
 			|| _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
 		/* get a source address of inbound SA */
 		error = ipsecdoi_id2sockaddr(iph2->id_p,
-					     (struct sockaddr *)&spidx.src,
-					     &spidx.prefs, &spidx.ul_proto);
+									 (struct sockaddr *)&spidx.src,
+									 &spidx.prefs, &spidx.ul_proto);
 		if (error)
 			goto purge;
 
@@ -3523,7 +3458,7 @@
 		 * for more detail, see above of this function.
 		 */
 		if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
-			error =
+			error = 
 				setscopeid((struct sockaddr *)&spidx.src,
 						   iph2->dst);
 			if (error)
@@ -3531,19 +3466,19 @@
 		}
 #endif
 
-		/* make sa_[src,dst] if both ID types are IP address and same */
+		/* make id[src,dst] if both ID types are IP address and same */
 		if (_XIDT(iph2->id_p) == idi2type
 			&& spidx.dst.ss_family == spidx.src.ss_family) {
-			iph2->sa_src =
+			iph2->src_id = 
 				dupsaddr((struct sockaddr *)&spidx.dst);
-			if (iph2->sa_src == NULL) {
+			if (iph2->src_id == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
 					 "allocation failed\n");
 				goto purge;
 			}
-			iph2->sa_dst =
+			iph2->dst_id = 
 				dupsaddr((struct sockaddr *)&spidx.src);
-			if (iph2->sa_dst == NULL) {
+			if (iph2->dst_id == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
 					 "allocation failed\n");
 				goto purge;
@@ -3561,12 +3496,12 @@
 		memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
 		switch (spidx.src.ss_family) {
 		case AF_INET:
-			spidx.prefs =
+			spidx.prefs = 
 				sizeof(struct in_addr) << 3;
 			break;
 #ifdef INET6
 		case AF_INET6:
-			spidx.prefs =
+			spidx.prefs = 
 				sizeof(struct in6_addr) << 3;
 			break;
 #endif
@@ -3604,7 +3539,7 @@
 	 */
 	if( created ){
 		struct secpolicy *p;
-
+		
 		p = getsp(&spidx);
 		if(p != NULL){
 			/* just do no test if p is NULL, because this probably just means
@@ -3669,7 +3604,7 @@
 	struct sockaddr *sp_addr0, *sa_addr0;
 {
 	struct sockaddr_in6 *sp_addr, *sa_addr;
-
+    
 	sp_addr = (struct sockaddr_in6 *)sp_addr0;
 	sa_addr = (struct sockaddr_in6 *)sa_addr0;
 
diff --git a/src/racoon/isakmp.h b/src/racoon/isakmp.h
index 16986a9..d0fd242 100644
--- a/src/racoon/isakmp.h
+++ b/src/racoon/isakmp.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp.h,v 1.7 2009/05/20 07:54:50 vanhu Exp $	*/
+/*	$NetBSD: isakmp.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: isakmp.h,v 1.11 2005/04/25 22:19:39 manubsd Exp */
 
@@ -36,8 +36,8 @@
 
 /* refer to RFC 2408 */
 
-#include <netinet/in.h>
-#include "isakmp_var.h"
+/* must include <netinet/in.h> first. */
+/* must include "isakmp_var.h" first. */
 
 #define INITIATOR	0	/* synonym sender */
 #define RESPONDER	1	/* synonym receiver */
@@ -133,7 +133,7 @@
 /* Exchange Type */
 #define ISAKMP_ETYPE_NONE	0	/* NONE */
 #define ISAKMP_ETYPE_BASE	1	/* Base */
-#define ISAKMP_ETYPE_IDENT	2	/* Identity Protection */
+#define ISAKMP_ETYPE_IDENT	2	/* Identity Proteciton */
 #define ISAKMP_ETYPE_AUTH	3	/* Authentication Only */
 #define ISAKMP_ETYPE_AGG	4	/* Aggressive */
 #define ISAKMP_ETYPE_INFO	5	/* Informational */
@@ -270,6 +270,11 @@
 #define ISAKMP_CERT_X509ATTR	10
 #define ISAKMP_CERT_PLAINRSA	11
 
+/* the method to get peers certificate */
+#define ISAKMP_GETCERT_PAYLOAD		1
+#define ISAKMP_GETCERT_LOCALFILE	2
+#define ISAKMP_GETCERT_DNS		3
+
 /* 3.10 Certificate Request Payload */
 struct isakmp_pl_cr {
 	struct isakmp_gen h;
@@ -379,8 +384,7 @@
 struct payload_list {
 	struct payload_list	*next, *prev;
 	vchar_t			*payload;
-	u_int8_t		payload_type;
-	u_int8_t		free_payload;
+	int			payload_type;
 };
 
 
diff --git a/src/racoon/isakmp_agg.c b/src/racoon/isakmp_agg.c
index 2e387fb..0d43883 100644
--- a/src/racoon/isakmp_agg.c
+++ b/src/racoon/isakmp_agg.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: isakmp_agg.c,v 1.16 2009/09/18 10:31:11 tteras Exp $	*/
+/*	$NetBSD: isakmp_agg.c,v 1.9 2006/09/30 21:49:37 manu Exp $	*/
 
 /* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -113,6 +113,8 @@
 	vchar_t *msg; /* must be null */
 {
 	struct payload_list *plist = NULL;
+	int need_cr = 0;
+	vchar_t *cr = NULL; 
 	int error = -1;
 #ifdef ENABLE_NATT
 	vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
@@ -133,6 +135,7 @@
 	vchar_t *vid_dpd = NULL;
 #endif
 
+
 	/* validity check */
 	if (msg != NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -154,7 +157,7 @@
 		goto end;
 
 	/* create SA payload for my proposal */
-	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->rmconf->proposal);
+	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
 	if (iph1->sa == NULL)
 		goto end;
 
@@ -177,8 +180,8 @@
 
 #ifdef ENABLE_HYBRID
 	/* Do we need Xauth VID? */
-	switch (iph1->rmconf->proposal->authmethod) {
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	switch (RMAUTHMETHOD(iph1)) {
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
@@ -186,10 +189,10 @@
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
 		if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
-			plog(LLV_ERROR, LOCATION, NULL,
+			plog(LLV_ERROR, LOCATION, NULL, 
 			     "Xauth vendor ID generation failed\n");
 		if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
-			plog(LLV_ERROR, LOCATION, NULL,
+			plog(LLV_ERROR, LOCATION, NULL, 
 			     "Unity vendor ID generation failed\n");
 		break;
 	default:
@@ -206,13 +209,26 @@
 		if (vid_frag == NULL)
 			plog(LLV_ERROR, LOCATION, NULL,
 			    "Frag vendorID construction failed\n");
-	}
+	}		
 #endif
 
+	/* create CR if need */
+	if (iph1->rmconf->send_cr
+	 && oakley_needcr(iph1->rmconf->proposal->authmethod)
+	 && iph1->rmconf->peerscertfile == NULL) {
+		need_cr = 1;
+		cr = oakley_getcr(iph1);
+		if (cr == NULL) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"failed to get cr buffer.\n");
+			goto end;
+		}
+	}
+
 	plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n",
 		s_oakley_attr_method(iph1->rmconf->proposal->authmethod));
 #ifdef HAVE_GSSAPI
-	if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+	if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
 		gssapi_get_itoken(iph1, &len);
 #endif
 
@@ -229,37 +245,33 @@
 	plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
 
 #ifdef HAVE_GSSAPI
-	if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
-		if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "Failed to get gssapi token.\n");
-			goto end;
-		}
+	if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+		gssapi_get_token_to_send(iph1, &gsstoken);
 		plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
 	}
 #endif
 	/* create isakmp CR payload */
-	if (oakley_needcr(iph1->rmconf->proposal->authmethod))
-		plist = oakley_append_cr(plist, iph1);
+	if (need_cr)
+		plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
 
 #ifdef ENABLE_FRAG
 	if (vid_frag)
 		plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
 #endif
 #ifdef ENABLE_NATT
-	/*
-	 * set VID payload for NAT-T if NAT-T
-	 * support allowed in the config file
+	/* 
+	 * set VID payload for NAT-T if NAT-T 
+	 * support allowed in the config file 
 	 */
-	if (iph1->rmconf->nat_traversal)
+	if (iph1->rmconf->nat_traversal) 
 		plist = isakmp_plist_append_natt_vids(plist, vid_natt);
 #endif
 #ifdef ENABLE_HYBRID
 	if (vid_xauth)
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    vid_xauth, ISAKMP_NPTYPE_VID);
 	if (vid_unity)
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    vid_unity, ISAKMP_NPTYPE_VID);
 #endif
 #ifdef ENABLE_DPD
@@ -277,7 +289,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	iph1->status = PHASE1ST_MSG1SENT;
@@ -285,6 +298,8 @@
 	error = 0;
 
 end:
+	if (cr)
+		vfree(cr);
 #ifdef HAVE_GSSAPI
 	if (gsstoken)
 		vfree(gsstoken);
@@ -328,6 +343,7 @@
 	struct isakmp_parse_t *pa;
 	vchar_t *satmp = NULL;
 	int error = -1;
+	int vid_numeric;
 	int ptype;
 #ifdef ENABLE_HYBRID
 	vchar_t *unity_vid;
@@ -409,12 +425,37 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_NATT
+			if (iph1->rmconf->nat_traversal && 
+			    natt_vendorid(vid_numeric))
+				natt_handle_vendorid(iph1, vid_numeric);
+#endif
+#ifdef ENABLE_HYBRID
+			switch (vid_numeric) {
+			case VENDORID_XAUTH:
+				iph1->mode_cfg->flags |= 
+				    ISAKMP_CFG_VENDORID_XAUTH;
+				break;
+
+			case VENDORID_UNITY:
+				iph1->mode_cfg->flags |= 
+				    ISAKMP_CFG_VENDORID_UNITY;
+				break;
+			default:
+				break;
+			}
+#endif
+#ifdef ENABLE_DPD
+			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
+				iph1->dpd_support=1;
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "remote supports DPD\n");
+			}
+#endif
 			break;
 		case ISAKMP_NPTYPE_N:
-			isakmp_log_notify(iph1,
-				(struct isakmp_pl_n *) pa->ptr,
-				"aggressive exchange");
+			isakmp_check_notify(pa->ptr, iph1);
 			break;
 #ifdef HAVE_GSSAPI
 		case ISAKMP_NPTYPE_GSS:
@@ -488,7 +529,7 @@
 	if (NATT_AVAILABLE(iph1)) {
 		struct natd_payload *natd = NULL;
 		int natd_verified;
-
+		
 		plog(LLV_INFO, LOCATION, iph1->remote,
 		     "Selected NAT-T version: %s\n",
 		     vid_string_by_id(iph1->natt_options->version));
@@ -496,9 +537,9 @@
 		/* set both bits first so that we can clear them
 		   upon verifying hashes */
 		iph1->natt_flags |= NAT_DETECTED;
-
+                        
 		while ((natd = TAILQ_FIRST(&natd_tree)) != NULL) {
-			/* this function will clear appropriate bits bits
+			/* this function will clear appropriate bits bits 
 			   from iph1->natt_flags */
 			natd_verified = natt_compare_addr_hash (iph1,
 				natd->payload, natd->seq);
@@ -506,7 +547,7 @@
 			plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
 				natd->seq - 1,
 				natd_verified ? "verified" : "doesn't match");
-
+			
 			vfree (natd->payload);
 
 			TAILQ_REMOVE(&natd_tree, natd, chain);
@@ -514,7 +555,7 @@
 		}
 
 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
-		      iph1->natt_flags & NAT_DETECTED ?
+		      iph1->natt_flags & NAT_DETECTED ? 
 		      		"detected:" : "not detected",
 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
@@ -546,7 +587,8 @@
 			/* message printed inner oakley_validate_auth() */
 			goto end;
 		}
-		evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, 
+		    EVTT_PEERPH1AUTH_FAILED, NULL);
 		isakmp_info_send_n1(iph1, ptype, NULL);
 		goto end;
 	}
@@ -574,10 +616,13 @@
 		VPTRINIT(iph1->dhpub_p);
 		VPTRINIT(iph1->nonce_p);
 		VPTRINIT(iph1->id_p);
-		VPTRINIT(iph1->cert_p);
-		VPTRINIT(iph1->crl_p);
+		oakley_delcert(iph1->cert_p);
+		iph1->cert_p = NULL;
+		oakley_delcert(iph1->crl_p);
+		iph1->crl_p = NULL;
 		VPTRINIT(iph1->sig_p);
-		VPTRINIT(iph1->cr_p);
+		oakley_delcert(iph1->cr_p);
+		iph1->cr_p = NULL;
 	}
 
 	return error;
@@ -624,15 +669,15 @@
 		goto end;
 	}
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
-#endif
+#endif  
 		/* set HASH payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->hash, ISAKMP_NPTYPE_HASH);
 		break;
 
@@ -655,11 +700,11 @@
 
 		/* add CERT payload if there */
 		if (need_cert)
-			plist = isakmp_plist_append(plist, iph1->cert,
-						    ISAKMP_NPTYPE_CERT);
+			plist = isakmp_plist_append(plist, 
+			    iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 
 		/* add SIG payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->sig, ISAKMP_NPTYPE_SIG);
 		break;
 
@@ -681,7 +726,7 @@
 			goto end;
 		}
 
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    gsshash, ISAKMP_NPTYPE_HASH);
 		break;
 #endif
@@ -692,26 +737,26 @@
 	if (NATT_AVAILABLE(iph1)) {
 		vchar_t *natd[2] = { NULL, NULL };
 
-		plog(LLV_INFO, LOCATION,
+		plog(LLV_INFO, LOCATION, 
 		    NULL, "Adding remote and local NAT-D payloads.\n");
 
 		if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			    "NAT-D hashing failed for %s\n",
+			    "NAT-D hashing failed for %s\n", 
 			    saddr2str(iph1->remote));
 			goto end;
 		}
 
 		if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			    "NAT-D hashing failed for %s\n",
+			    "NAT-D hashing failed for %s\n", 
 			    saddr2str(iph1->local));
 			goto end;
 		}
 
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    natd[0], iph1->natt_options->payload_nat_d);
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    natd[1], iph1->natt_options->payload_nat_d);
 	}
 #endif
@@ -815,7 +860,37 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			vid_numeric = handle_vendorid(iph1, pa->ptr);
+			vid_numeric = check_vendorid(pa->ptr);
+
+#ifdef ENABLE_NATT
+			if (iph1->rmconf->nat_traversal &&
+			    natt_vendorid(vid_numeric)) {
+				natt_handle_vendorid(iph1, vid_numeric);
+				break;
+			}
+#endif
+#ifdef ENABLE_HYBRID
+			switch (vid_numeric) {
+			case VENDORID_XAUTH:
+				iph1->mode_cfg->flags |= 
+				    ISAKMP_CFG_VENDORID_XAUTH;
+				break;
+
+			case VENDORID_UNITY:
+				iph1->mode_cfg->flags |= 
+				    ISAKMP_CFG_VENDORID_UNITY;
+				break;
+			default:
+				break;
+			}
+#endif
+#ifdef ENABLE_DPD
+			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
+				iph1->dpd_support=1;
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "remote supports DPD\n");
+			}
+#endif
 #ifdef ENABLE_FRAG
 			if ((vid_numeric == VENDORID_FRAG) &&
 			    (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG))
@@ -895,7 +970,8 @@
 		VPTRINIT(iph1->dhpub_p);
 		VPTRINIT(iph1->nonce_p);
 		VPTRINIT(iph1->id_p);
-		VPTRINIT(iph1->cr_p);
+		oakley_delcert(iph1->cr_p);
+		iph1->cr_p = NULL;
 	}
 
 	return error;
@@ -915,7 +991,9 @@
 	vchar_t *msg;
 {
 	struct payload_list *plist = NULL;
+	int need_cr = 0;
 	int need_cert = 0;
+	vchar_t *cr = NULL;
 	int error = -1;
 #ifdef ENABLE_HYBRID
 	vchar_t *xauth_vid = NULL;
@@ -979,7 +1057,7 @@
 		goto end;
 
 #ifdef HAVE_GSSAPI
-	if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+	if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
 		gssapi_get_rtoken(iph1, &gsslen);
 #endif
 
@@ -995,6 +1073,19 @@
 		goto end;
 	}
 
+	/* create CR if need */
+	if (iph1->rmconf->send_cr
+	 && oakley_needcr(iph1->approval->authmethod)
+	 && iph1->rmconf->peerscertfile == NULL) {
+		need_cr = 1;
+		cr = oakley_getcr(iph1);
+		if (cr == NULL) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"failed to get cr buffer.\n");
+			goto end;
+		}
+	}
+
 #ifdef ENABLE_NATT
 	/* Has the peer announced NAT-T? */
 	if (NATT_AVAILABLE(iph1)) {
@@ -1033,34 +1124,35 @@
 	}
 #endif
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 #endif
 		/* set SA payload to reply */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->sa_ret, ISAKMP_NPTYPE_SA);
 
 		/* create isakmp KE payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->dhpub, ISAKMP_NPTYPE_KE);
 
 		/* create isakmp NONCE payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->nonce, ISAKMP_NPTYPE_NONCE);
 
 		/* create isakmp ID payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->id, ISAKMP_NPTYPE_ID);
 
 		/* create isakmp HASH payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->hash, ISAKMP_NPTYPE_HASH);
 
 		/* create isakmp CR payload if needed */
-		if (oakley_needcr(iph1->approval->authmethod))
-			plist = oakley_append_cr(plist, iph1);
+		if (need_cr)
+			plist = isakmp_plist_append(plist, 
+			    cr, ISAKMP_NPTYPE_CR);
 		break;
 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
@@ -1082,33 +1174,34 @@
 			need_cert = 1;
 
 		/* set SA payload to reply */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->sa_ret, ISAKMP_NPTYPE_SA);
 
 		/* create isakmp KE payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->dhpub, ISAKMP_NPTYPE_KE);
 
 		/* create isakmp NONCE payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->nonce, ISAKMP_NPTYPE_NONCE);
 
 		/* add ID payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->id, ISAKMP_NPTYPE_ID);
 
 		/* add CERT payload if there */
 		if (need_cert)
-			plist = isakmp_plist_append(plist, iph1->cert,
-						    ISAKMP_NPTYPE_CERT);
+			plist = isakmp_plist_append(plist, 
+			    iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 
 		/* add SIG payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->sig, ISAKMP_NPTYPE_SIG);
 
 		/* create isakmp CR payload if needed */
-		if (oakley_needcr(iph1->approval->authmethod))
-			plist = oakley_append_cr(plist, iph1);
+		if (need_cr)
+			plist = isakmp_plist_append(plist, 
+			    cr, ISAKMP_NPTYPE_CR);
 		break;
 
 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
@@ -1126,9 +1219,9 @@
 				plog(LLV_ERROR, LOCATION, NULL,
 					"failed to wrap hash\n");
 				/*
-				 * This is probably due to the GSS
-				 * roundtrips not being finished yet.
-				 * Return this error in the hope that
+				 * This is probably due to the GSS 
+				 * roundtrips not being finished yet. 
+				 * Return this error in the hope that 
 				 * a fallback to main mode will be done.
 				 */
 				isakmp_info_send_n1(iph1,
@@ -1136,8 +1229,8 @@
 				goto end;
 			}
 			if (iph1->approval->gssid != NULL)
-				gss_sa = ipsecdoi_setph1proposal(iph1->rmconf,
-								 iph1->approval);
+				gss_sa = 
+				    ipsecdoi_setph1proposal(iph1->approval);  
 			else
 				gss_sa = iph1->sa_ret;
 
@@ -1145,32 +1238,28 @@
 				free_gss_sa = 1;
 
 			/* set SA payload to reply */
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			    gss_sa, ISAKMP_NPTYPE_SA);
 
 			/* create isakmp KE payload */
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			    iph1->dhpub, ISAKMP_NPTYPE_KE);
 
 			/* create isakmp NONCE payload */
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			    iph1->nonce, ISAKMP_NPTYPE_NONCE);
 
 			/* create isakmp ID payload */
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			    iph1->id, ISAKMP_NPTYPE_ID);
 
 			/* create GSS payload */
-			if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
-				plog(LLV_ERROR, LOCATION, NULL,
-				    "Failed to get gssapi token.\n");
-				goto end;
-			}
-			plist = isakmp_plist_append(plist,
+			gssapi_get_token_to_send(iph1, &gsstoken);
+			plist = isakmp_plist_append(plist, 
 			    gsstoken, ISAKMP_NPTYPE_GSS);
 
 			/* create isakmp HASH payload */
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			    gsshash, ISAKMP_NPTYPE_HASH);
 
 			/* append vendor id, if needed */
@@ -1186,7 +1275,7 @@
 			    "Cannot create Xauth vendor ID\n");
 			goto end;
 		}
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    xauth_vid, ISAKMP_NPTYPE_VID);
 	}
 
@@ -1196,7 +1285,7 @@
 			    "Cannot create Unity vendor ID\n");
 			goto end;
 		}
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    unity_vid, ISAKMP_NPTYPE_VID);
 	}
 #endif
@@ -1229,7 +1318,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	/* the sending message is added to the received-list. */
@@ -1244,6 +1334,8 @@
 	error = 0;
 
 end:
+	if (cr)
+		vfree(cr);
 #ifdef ENABLE_HYBRID
 	if (xauth_vid)
 		vfree(xauth_vid);
@@ -1286,7 +1378,9 @@
 	vchar_t *msg = NULL;
 	vchar_t *pbuf = NULL;
 	struct isakmp_parse_t *pa;
-	int error = -1, ptype;
+	int error = -1;
+	int ptype;
+
 #ifdef ENABLE_NATT
 	int natd_seq = 0;
 #endif
@@ -1324,7 +1418,7 @@
 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 		case ISAKMP_NPTYPE_CERT:
 			if (oakley_savecert(iph1, pa->ptr) < 0)
@@ -1335,9 +1429,7 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_N:
-			isakmp_log_notify(iph1,
-				(struct isakmp_pl_n *) pa->ptr,
-				"aggressive exchange");
+			isakmp_check_notify(pa->ptr, iph1);
 			break;
 
 #ifdef ENABLE_NATT
@@ -1348,20 +1440,20 @@
 			{
 				vchar_t *natd_received = NULL;
 				int natd_verified;
-
+				
 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
 					goto end;
-
+				
 				if (natd_seq == 0)
 					iph1->natt_flags |= NAT_DETECTED;
-
+				
 				natd_verified = natt_compare_addr_hash (iph1,
 					natd_received, natd_seq++);
-
+				
 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
 					natd_seq - 1,
 					natd_verified ? "verified" : "doesn't match");
-
+				
 				vfree (natd_received);
 				break;
 			}
@@ -1381,7 +1473,7 @@
 #ifdef ENABLE_NATT
 	if (NATT_AVAILABLE(iph1))
 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
-		      iph1->natt_flags & NAT_DETECTED ?
+		      iph1->natt_flags & NAT_DETECTED ? 
 		      		"detected:" : "not detected",
 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
@@ -1394,7 +1486,8 @@
 			/* message printed inner oakley_validate_auth() */
 			goto end;
 		}
-		evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, 
+		    EVTT_PEERPH1AUTH_FAILED, NULL);
 		isakmp_info_send_n1(iph1, ptype, NULL);
 		goto end;
 	}
@@ -1409,8 +1502,10 @@
 	if (msg)
 		vfree(msg);
 	if (error) {
-		VPTRINIT(iph1->cert_p);
-		VPTRINIT(iph1->crl_p);
+		oakley_delcert(iph1->cert_p);
+		iph1->cert_p = NULL;
+		oakley_delcert(iph1->crl_p);
+		iph1->crl_p = NULL;
 		VPTRINIT(iph1->sig_p);
 	}
 
diff --git a/src/racoon/isakmp_base.c b/src/racoon/isakmp_base.c
index f37d51e..3ac0b72 100644
--- a/src/racoon/isakmp_base.c
+++ b/src/racoon/isakmp_base.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_base.c,v 1.12 2009/03/12 10:57:26 tteras Exp $	*/
+/*	$NetBSD: isakmp_base.c,v 1.7 2006/10/02 21:51:33 manu Exp $	*/
 
 /*	$KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane Exp $	*/
 
@@ -143,8 +143,7 @@
 		goto end;
 
 	/* create SA payload for my proposal */
-	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf,
-					   iph1->rmconf->proposal);
+	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
 	if (iph1->sa == NULL)
 		goto end;
 
@@ -155,8 +154,8 @@
 
 #ifdef ENABLE_HYBRID
         /* Do we need Xauth VID? */
-        switch (iph1->rmconf->proposal->authmethod) {
-        case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+        switch (RMAUTHMETHOD(iph1)) {
+        case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
         case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
         case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
         case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
@@ -251,7 +250,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	iph1->status = PHASE1ST_MSG1SENT;
@@ -297,6 +297,7 @@
 	struct isakmp_parse_t *pa;
 	vchar_t *satmp = NULL;
 	int error = -1;
+	int vid_numeric;
 #ifdef ENABLE_HYBRID
 	vchar_t *unity_vid;
 	vchar_t *xauth_vid;
@@ -341,7 +342,34 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_NATT
+			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
+			  natt_handle_vendorid(iph1, vid_numeric);
+#endif
+#ifdef ENABLE_HYBRID
+			switch (vid_numeric) {
+			case VENDORID_XAUTH:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_XAUTH;
+				break;
+
+			case VENDORID_UNITY:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_UNITY;
+				break;
+
+			default:
+				break;
+			}
+#endif
+#ifdef ENABLE_DPD
+			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
+				iph1->dpd_support=1;
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "remote supports DPD\n");
+			}
+#endif
 			break;
 		default:
 			/* don't send information, see ident_r1recv() */
@@ -434,7 +462,7 @@
 		goto end;
 
 	/* generate SKEYID to compute hash if not signature mode */
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
 #ifdef ENABLE_HYBRID
@@ -456,10 +484,10 @@
 	iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE);
 	if (iph1->hash == NULL)
 		goto end;
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
 #endif
@@ -493,16 +521,16 @@
 			need_cert = 1;
 
 		/* create isakmp KE payload */
-		plist = isakmp_plist_append(plist, iph1->dhpub,
-					    ISAKMP_NPTYPE_KE);
+		plist = isakmp_plist_append(plist, 
+		    iph1->dhpub, ISAKMP_NPTYPE_KE);
 
 		/* add CERT payload if there */
 		if (need_cert)
-			plist = isakmp_plist_append(plist,  iph1->cert,
-						    ISAKMP_NPTYPE_CERT);
+			plist = isakmp_plist_append(plist, 
+			    iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 
 		/* add SIG payload */
-		plist = isakmp_plist_append(plist,
+		plist = isakmp_plist_append(plist, 
 		    iph1->sig, ISAKMP_NPTYPE_SIG);
 
 		break;
@@ -551,7 +579,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	/* the sending message is added to the received-list. */
@@ -585,7 +614,8 @@
 {
 	vchar_t *pbuf = NULL;
 	struct isakmp_parse_t *pa;
-	int error = -1, ptype;
+	int error = -1;
+	int ptype;
 #ifdef ENABLE_NATT
 	vchar_t	*natd_received;
 	int natd_seq = 0, natd_verified;
@@ -624,7 +654,7 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 
 #ifdef ENABLE_NATT
@@ -686,7 +716,8 @@
 			/* message printed inner oakley_validate_auth() */
 			goto end;
 		}
-		evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, 
+		    EVTT_PEERPH1AUTH_FAILED, NULL);
 		isakmp_info_send_n1(iph1, ptype, NULL);
 		goto end;
 	}
@@ -697,7 +728,7 @@
 		goto end;
 
 	/* generate SKEYID to compute hash if signature mode */
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
 #ifdef ENABLE_HYBRID
@@ -738,8 +769,10 @@
 
 	if (error) {
 		VPTRINIT(iph1->dhpub_p);
-		VPTRINIT(iph1->cert_p);
-		VPTRINIT(iph1->crl_p);
+		oakley_delcert(iph1->cert_p);
+		iph1->cert_p = NULL;
+		oakley_delcert(iph1->crl_p);
+		iph1->crl_p = NULL;
 		VPTRINIT(iph1->sig_p);
 	}
 
@@ -796,6 +829,9 @@
 	}
 
 	/* validate the type of next payload */
+	/*
+	 * NOTE: XXX even if multiple VID, we'll silently ignore those.
+	 */
 	pbuf = isakmp_parse(msg);
 	if (pbuf == NULL)
 		goto end;
@@ -827,12 +863,39 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			vid_numeric = handle_vendorid(iph1, pa->ptr);
+			vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_NATT
+			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
+				natt_handle_vendorid(iph1, vid_numeric);
+#endif
 #ifdef ENABLE_FRAG
 			if ((vid_numeric == VENDORID_FRAG) &&
 			    (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE))
 				iph1->frag = 1;
 #endif
+#ifdef ENABLE_HYBRID
+			switch (vid_numeric) {
+			case VENDORID_XAUTH:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_XAUTH;
+				break;
+
+			case VENDORID_UNITY:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_UNITY;
+				break;
+
+			default:
+				break;
+			}
+#endif
+#ifdef ENABLE_DPD
+			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
+				iph1->dpd_support=1;
+				plog(LLV_DEBUG, LOCATION, NULL,
+					 "remote supports DPD\n");
+			}
+#endif 
 			break;
 		default:
 			/* don't send information, see ident_r1recv() */
@@ -1010,7 +1073,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1) {
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1) {
 		iph1 = NULL;
 		goto end;
 	}
@@ -1066,7 +1130,8 @@
 {
 	vchar_t *pbuf = NULL;
 	struct isakmp_parse_t *pa;
-	int error = -1, ptype;
+	int error = -1;
+	int ptype;
 #ifdef ENABLE_NATT
 	int natd_seq = 0;
 #endif
@@ -1106,7 +1171,7 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 
 #ifdef ENABLE_NATT
@@ -1177,7 +1242,8 @@
 			/* message printed inner oakley_validate_auth() */
 			goto end;
 		}
-		evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, 
+		    EVTT_PEERPH1AUTH_FAILED, NULL);
 		isakmp_info_send_n1(iph1, ptype, NULL);
 		goto end;
 	}
@@ -1192,8 +1258,10 @@
 
 	if (error) {
 		VPTRINIT(iph1->dhpub_p);
-		VPTRINIT(iph1->cert_p);
-		VPTRINIT(iph1->crl_p);
+		oakley_delcert(iph1->cert_p);
+		iph1->cert_p = NULL;
+		oakley_delcert(iph1->crl_p);
+		iph1->crl_p = NULL;
 		VPTRINIT(iph1->sig_p);
 	}
 
@@ -1226,7 +1294,7 @@
 
 	/* generate HASH to send */
 	plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
@@ -1261,7 +1329,7 @@
 	if (iph1->hash == NULL)
 		goto end;
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
@@ -1301,17 +1369,16 @@
 			need_cert = 1;
 
 		/* create isakmp KE payload */
-		plist = isakmp_plist_append(plist, iph1->dhpub,
-					    ISAKMP_NPTYPE_KE);
+		plist = isakmp_plist_append(plist, 
+		    iph1->dhpub, ISAKMP_NPTYPE_KE);
 
 		/* add CERT payload if there */
 		if (need_cert)
-			plist = isakmp_plist_append(plist, iph1->cert,
-						    ISAKMP_NPTYPE_CERT);
-
+			plist = isakmp_plist_append(plist, 
+			    iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 		/* add SIG payload */
-		plist = isakmp_plist_append(plist, iph1->sig,
-					    ISAKMP_NPTYPE_SIG);
+		plist = isakmp_plist_append(plist, 
+		    iph1->sig, ISAKMP_NPTYPE_SIG);
 		break;
 #ifdef HAVE_GSSAPI
 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
diff --git a/src/racoon/isakmp_cfg.c b/src/racoon/isakmp_cfg.c
index 65703bb..ddf57c0 100644
--- a/src/racoon/isakmp_cfg.c
+++ b/src/racoon/isakmp_cfg.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_cfg.c,v 1.24 2010/09/21 13:14:17 vanhu Exp $	*/
+/*	$NetBSD: isakmp_cfg.c,v 1.12.6.4 2008/11/27 15:25:20 vanhu Exp $	*/
 
 /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
 
@@ -39,7 +39,7 @@
 #include <sys/queue.h>
 
 #ifndef ANDROID_PATCHED
-#include <utmpx.h>
+#include <utmp.h>
 #endif
 #if defined(__APPLE__) && defined(__MACH__)
 #include <util.h>
@@ -116,8 +116,6 @@
 #endif
 static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 
 				 struct isakmp_data *, in_addr_t *);
-static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *, 
-				 struct isakmp_data *, in_addr_t *, in_addr_t *);
 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
 static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
 				      struct isakmp_data *, in_addr_t *, int);
@@ -450,8 +448,8 @@
 	
 	if ((iph1->status == PHASE1ST_ESTABLISHED) && 
 	    iph1->rmconf->mode_cfg) {
-		switch (iph1->approval->authmethod) {
-		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+		switch (AUTHMETHOD(iph1)) {
+		case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 		/* Unimplemented */
 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: 
@@ -477,7 +475,8 @@
 			    "Cannot allocate memory: %s\n", strerror(errno));
 		} else {
 			memcpy(buf->v, attrpl + 1, buf->l);
-			evt_phase1(iph1, EVT_PHASE1_MODE_CFG, buf);
+			EVT_PUSH(iph1->local, iph1->remote, 
+			    EVTT_ISAKMP_CFG_DONE, buf);
 			vfree(buf);
 		}
 	}
@@ -632,7 +631,7 @@
 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
 
 	if (iph1->status == PHASE1ST_ESTABLISHED) {
-		switch (iph1->approval->authmethod) {
+		switch (AUTHMETHOD(iph1)) {
 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
 		/* Unimplemented */
@@ -734,8 +733,7 @@
 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
 
 	if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
-		if (iph1->status == PHASE1ST_ESTABLISHED ||
-		    iph1->status == PHASE1ST_DYING)
+		if (iph1->status == PHASE1ST_ESTABLISHED)
 			isakmp_info_send_d1(iph1);
 		remph1(iph1);
 		delph1(iph1);
@@ -905,15 +903,8 @@
 		break;
 
 	case INTERNAL_IP4_SUBNET:
-		if(isakmp_cfg_config.splitnet_count > 0){
-			return isakmp_cfg_addrnet4(iph1, attr,
-						    &isakmp_cfg_config.splitnet_list->network.addr4.s_addr,
-						    &isakmp_cfg_config.splitnet_list->network.mask4.s_addr);
-		}else{
-			plog(LLV_INFO, LOCATION, NULL,
-			     "%s requested but no splitnet in configuration\n",
-			     s_isakmp_cfg_type(type));
-		}
+		return isakmp_cfg_addr4(iph1, 
+		    attr, &isakmp_cfg_config.network4);
 		break;
 
 	default:
@@ -1053,36 +1044,6 @@
 }
 
 static vchar_t *
-isakmp_cfg_addrnet4(iph1, attr, addr, mask)
-	struct ph1handle *iph1;
-	struct isakmp_data *attr;
-	in_addr_t *addr;
-	in_addr_t *mask;
-{
-	vchar_t *buffer;
-	struct isakmp_data *new;
-	size_t len;
-	in_addr_t netbuff[2];
-
-	len = sizeof(netbuff);
-	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
-		return NULL;
-	}
-
-	new = (struct isakmp_data *)buffer->v;
-
-	new->type = attr->type;
-	new->lorv = htons(len);
-	netbuff[0]=*addr;
-	netbuff[1]=*mask;
-	memcpy(new + 1, netbuff, len);
-	
-	return buffer;
-}
-
-
-static vchar_t *
 isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
 	struct ph1handle *iph1;
 	struct isakmp_data *attr;
@@ -1168,7 +1129,7 @@
 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
 
 	/* Check if phase 1 is established */
-	if ((iph1->status < PHASE1ST_ESTABLISHED) ||
+	if ((iph1->status != PHASE1ST_ESTABLISHED) || 
 	    (iph1->local == NULL) ||
 	    (iph1->remote == NULL)) {
 		plog(LLV_ERROR, LOCATION, NULL, 
@@ -1192,6 +1153,16 @@
 		goto end;
 	}
 
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
+	if (set_port(iph2->dst, 0) == NULL ||
+	    set_port(iph2->src, 0) == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		     "invalid family: %d\n", iph1->remote->sa_family);
+		delph2(iph2);
+		goto end;
+	}
+#endif
+	iph2->ph1 = iph1;
 	iph2->side = INITIATOR;
 	iph2->status = PHASE2ST_START;
 
@@ -1210,7 +1181,7 @@
 		}
 
 		/* generate HASH(1) */
-		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
+		hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
 		if (hash == NULL) {
 			delph2(iph2);
 			goto end;
@@ -1309,6 +1280,7 @@
 	if (iph2->sendbuf != NULL)
 		vfree(iph2->sendbuf);
 
+	unbindph12(iph2);
 	remph2(iph2);
 	delph2(iph2);
 end:
@@ -1522,6 +1494,24 @@
 	struct ph1handle *iph1;
 	int inout;
 {
+	/* For first time use, initialize Radius */
+	if (radius_acct_state == NULL) {
+		if ((radius_acct_state = rad_acct_open()) == NULL) {
+			plog(LLV_ERROR, LOCATION, NULL,
+			    "Cannot init librradius\n");
+			return -1;
+		}
+
+		if (rad_config(radius_acct_state, NULL) != 0) {
+			 plog(LLV_ERROR, LOCATION, NULL,
+			     "Cannot open librarius config file: %s\n",
+			     rad_strerror(radius_acct_state));
+			  rad_close(radius_acct_state);
+			  radius_acct_state = NULL;
+			  return -1;
+		}
+	}
+
 	if (rad_create_request(radius_acct_state, 
 	    RAD_ACCOUNTING_REQUEST) != 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -1665,7 +1655,8 @@
 	int inout;
 {
 	int error = 0;
-	struct utmpx ut;
+	struct utmp ut;
+	char term[UT_LINESIZE];
 	char addr[NI_MAXHOST];
 	
 	if (usr == NULL || usr[0]=='\0') {
@@ -1674,33 +1665,36 @@
 		return -1;
 	}
 
-	memset(&ut, 0, sizeof ut);
-	gettimeofday((struct timeval *)&ut.ut_tv, NULL);
-	snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
+	sprintf(term, TERMSPEC, port);
 
 	switch (inout) {
 	case ISAKMP_CFG_LOGIN:
-		ut.ut_type = USER_PROCESS;
-		strncpy(ut.ut_user, usr, sizeof ut.ut_user);
+		strncpy(ut.ut_name, usr, UT_NAMESIZE);
+		ut.ut_name[UT_NAMESIZE - 1] = '\0';
+
+		strncpy(ut.ut_line, term, UT_LINESIZE);
+		ut.ut_line[UT_LINESIZE - 1] = '\0';
 
 		GETNAMEINFO_NULL(raddr, addr);
-		strncpy(ut.ut_host, addr, sizeof ut.ut_host);
+		strncpy(ut.ut_host, addr, UT_HOSTSIZE);
+		ut.ut_host[UT_HOSTSIZE - 1] = '\0';
 
+		ut.ut_time = time(NULL);
+ 
 		plog(LLV_INFO, LOCATION, NULL,
 			"Accounting : '%s' logging on '%s' from %s.\n",
-			ut.ut_user, ut.ut_id, addr);
+			ut.ut_name, ut.ut_line, ut.ut_host);
 
-		pututxline(&ut);
+		login(&ut);
 
 		break;
 	case ISAKMP_CFG_LOGOUT:	
-		ut.ut_type = DEAD_PROCESS;
 
 		plog(LLV_INFO, LOCATION, NULL,
 			"Accounting : '%s' unlogging from '%s'.\n",
-			usr, ut.ut_id);
+			usr, term);
 
-		pututxline(&ut);
+		logout(term);
 
 		break;
 	default:
@@ -1877,7 +1871,6 @@
 	char addrstr[IP_MAX];
 	char addrlist[IP_MAX * MAXNS + MAXNS];
 	char *splitlist = addrlist;
-	char *splitlist_cidr;
 	char defdom[MAXPATHLEN + 1];
 	int cidr, tmp;
 	char cidrstr[4];
@@ -2018,14 +2011,10 @@
 	}
 
 	/* Split networks */
-	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
-		splitlist = 
-		    splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
-		splitlist_cidr = 
-		    splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
-	} else {
+	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE)
+		splitlist = splitnet_list_2str(iph1->mode_cfg->split_include);
+	else {
 		splitlist = addrlist;
-		splitlist_cidr = addrlist;
 		addrlist[0] = '\0';
 	}
 
@@ -2033,25 +2022,13 @@
 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
 		return -1;
 	}
-	if (script_env_append(envp, envc, 
-	    "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "Cannot set SPLIT_INCLUDE_CIDR\n");
-		return -1;
-	}
 	if (splitlist != addrlist)
 		racoon_free(splitlist);
-	if (splitlist_cidr != addrlist)
-		racoon_free(splitlist_cidr);
 
-	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
-		splitlist =
-		    splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
-		splitlist_cidr =
-		    splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
-	} else {
+	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL)
+		splitlist = splitnet_list_2str(iph1->mode_cfg->split_local);
+	else {
 		splitlist = addrlist;
-		splitlist_cidr = addrlist;
 		addrlist[0] = '\0';
 	}
 
@@ -2059,16 +2036,8 @@
 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
 		return -1;
 	}
-	if (script_env_append(envp, envc,
-	    "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "Cannot set SPLIT_LOCAL_CIDR\n");
-		return -1;
-	}
 	if (splitlist != addrlist)
 		racoon_free(splitlist);
-	if (splitlist_cidr != addrlist)
-		racoon_free(splitlist_cidr);
 	
 	return 0;
 }
diff --git a/src/racoon/isakmp_frag.c b/src/racoon/isakmp_frag.c
index ebba34b..6fac6a2 100644
--- a/src/racoon/isakmp_frag.c
+++ b/src/racoon/isakmp_frag.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_frag.c,v 1.5 2009/04/22 11:24:20 tteras Exp $	*/
+/*	$NetBSD: isakmp_frag.c,v 1.4.6.1 2009/04/22 11:25:35 tteras Exp $	*/
 
 /* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */
 
diff --git a/src/racoon/isakmp_ident.c b/src/racoon/isakmp_ident.c
index a9c3a01..1e00dc4 100644
--- a/src/racoon/isakmp_ident.c
+++ b/src/racoon/isakmp_ident.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: isakmp_ident.c,v 1.13 2009/09/18 10:31:11 tteras Exp $	*/
+/*	$NetBSD: isakmp_ident.c,v 1.6 2006/10/02 21:41:59 manu Exp $	*/
 
 /* Id: isakmp_ident.c,v 1.21 2006/04/06 16:46:08 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -86,13 +86,12 @@
 #include "isakmp_xauth.h"
 #include "isakmp_cfg.h"
 #endif
-#ifdef ENABLE_FRAG
+#ifdef ENABLE_FRAG 
 #include "isakmp_frag.h"
 #endif
 
 static vchar_t *ident_ir2mx __P((struct ph1handle *));
 static vchar_t *ident_ir3mx __P((struct ph1handle *));
-static int ident_recv_n __P((struct ph1handle *, struct isakmp_gen *));
 
 /* %%%
  * begin Identity Protection Mode as initiator.
@@ -115,13 +114,13 @@
 	vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
 	int i;
 #endif
-#ifdef ENABLE_HYBRID
+#ifdef ENABLE_HYBRID  
 	vchar_t *vid_xauth = NULL;
 	vchar_t *vid_unity = NULL;
 #endif
-#ifdef ENABLE_FRAG
+#ifdef ENABLE_FRAG 
 	vchar_t *vid_frag = NULL;
-#endif
+#endif 
 #ifdef ENABLE_DPD
 	vchar_t *vid_dpd = NULL;
 #endif
@@ -142,8 +141,7 @@
 	isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
 
 	/* create SA payload for my proposal */
-	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf,
-					   iph1->rmconf->proposal);
+	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
 	if (iph1->sa == NULL)
 		goto end;
 
@@ -152,13 +150,13 @@
 
 #ifdef ENABLE_NATT
 	/* set VID payload for NAT-T if NAT-T support allowed in the config file */
-	if (iph1->rmconf->nat_traversal)
+	if (iph1->rmconf->nat_traversal) 
 		plist = isakmp_plist_append_natt_vids(plist, vid_natt);
 #endif
 #ifdef ENABLE_HYBRID
 	/* Do we need Xauth VID? */
-	switch (iph1->rmconf->proposal->authmethod) {
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	switch (RMAUTHMETHOD(iph1)) {
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
@@ -171,12 +169,12 @@
 		else
 			plist = isakmp_plist_append(plist,
 			    vid_xauth, ISAKMP_NPTYPE_VID);
-
+			
 		if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
 			plog(LLV_ERROR, LOCATION, NULL,
 			     "Unity vendor ID generation failed\n");
 		else
-			plist = isakmp_plist_append(plist,
+                	plist = isakmp_plist_append(plist,
 			    vid_unity, ISAKMP_NPTYPE_VID);
 		break;
 	default:
@@ -191,7 +189,7 @@
 		} else {
 			vid_frag = isakmp_frag_addcap(vid_frag,
 			    VENDORID_FRAG_IDENT);
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			    vid_frag, ISAKMP_NPTYPE_VID);
 		}
 	}
@@ -212,7 +210,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	iph1->status = PHASE1ST_MSG1SENT;
@@ -221,9 +220,9 @@
 
 end:
 #ifdef ENABLE_FRAG
-	if (vid_frag)
+	if (vid_frag) 
 		vfree(vid_frag);
-#endif
+#endif  
 #ifdef ENABLE_NATT
 	for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
 		vfree(vid_natt[i]);
@@ -258,6 +257,7 @@
 	struct isakmp_parse_t *pa;
 	vchar_t *satmp = NULL;
 	int error = -1;
+	int vid_numeric;
 
 	/* validity check */
 	if (iph1->status != PHASE1ST_MSG1SENT) {
@@ -299,7 +299,31 @@
 
 		switch (pa->type) {
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_NATT
+			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
+			  natt_handle_vendorid(iph1, vid_numeric);
+#endif
+#ifdef ENABLE_HYBRID
+			switch (vid_numeric) {
+			case VENDORID_XAUTH:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_XAUTH;
+				break;
+	
+			case VENDORID_UNITY:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_UNITY;
+				break;
+	
+			default:
+				break;
+			}
+#endif  
+#ifdef ENABLE_DPD
+			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
+				iph1->dpd_support=1;
+#endif
 			break;
 		default:
 			/* don't send information, see ident_r1recv() */
@@ -377,7 +401,7 @@
 		goto end;
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
 	    gssapi_get_itoken(iph1, NULL) < 0)
 		goto end;
 #endif
@@ -392,7 +416,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	/* the sending message is added to the received-list. */
@@ -460,7 +485,7 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 		case ISAKMP_NPTYPE_CR:
 			if (oakley_savecr(iph1, pa->ptr) < 0)
@@ -482,21 +507,21 @@
 				natd_received = NULL;
 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
 					goto end;
-
+                        
 				/* set both bits first so that we can clear them
 				   upon verifying hashes */
 				if (natd_seq == 0)
 					iph1->natt_flags |= NAT_DETECTED;
-
-				/* this function will clear appropriate bits bits
+                        
+				/* this function will clear appropriate bits bits 
 				   from iph1->natt_flags */
 				natd_verified = natt_compare_addr_hash (iph1,
 					natd_received, natd_seq++);
-
+                        
 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
 					natd_seq - 1,
 					natd_verified ? "verified" : "doesn't match");
-
+                        
 				vfree (natd_received);
 				break;
 			}
@@ -516,7 +541,7 @@
 #ifdef ENABLE_NATT
 	if (NATT_AVAILABLE(iph1)) {
 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
-		      iph1->natt_flags & NAT_DETECTED ?
+		      iph1->natt_flags & NAT_DETECTED ? 
 		      		"detected:" : "not detected",
 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
@@ -552,7 +577,8 @@
 		VPTRINIT(iph1->dhpub_p);
 		VPTRINIT(iph1->nonce_p);
 		VPTRINIT(iph1->id_p);
-		VPTRINIT(iph1->cr_p);
+		oakley_delcert(iph1->cr_p);
+		iph1->cr_p = NULL;
 	}
 
 	return error;
@@ -604,7 +630,7 @@
 		goto end;
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
 	    gssapi_more_tokens(iph1)) {
 		plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n");
 		if (gssapi_get_itoken(iph1, &len) < 0)
@@ -631,7 +657,8 @@
 		goto end;
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	/* the sending message is added to the received-list. */
@@ -727,10 +754,10 @@
 			break;
 #endif
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 		case ISAKMP_NPTYPE_N:
-			ident_recv_n(iph1, pa->ptr);
+			isakmp_check_notify(pa->ptr, iph1);
 			break;
 		default:
 			/* don't send information, see ident_r1recv() */
@@ -761,7 +788,8 @@
 				/* msg printed inner oakley_validate_auth() */
 				goto end;
 			}
-			evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
+			EVT_PUSH(iph1->local, iph1->remote, 
+			    EVTT_PEERPH1AUTH_FAILED, NULL);
 			isakmp_info_send_n1(iph1, type, NULL);
 			goto end;
 		}
@@ -784,7 +812,7 @@
 	 * If we got a GSS token, we need to this roundtrip again.
 	 */
 #ifdef HAVE_GSSAPI
-	iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED :
+	iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED : 
 	    PHASE1ST_MSG4RECEIVED;
 #else
 	iph1->status = PHASE1ST_MSG4RECEIVED;
@@ -804,8 +832,10 @@
 
 	if (error) {
 		VPTRINIT(iph1->id_p);
-		VPTRINIT(iph1->cert_p);
-		VPTRINIT(iph1->crl_p);
+		oakley_delcert(iph1->cert_p);
+		iph1->cert_p = NULL;
+		oakley_delcert(iph1->crl_p);
+		iph1->crl_p = NULL;
 		VPTRINIT(iph1->sig_p);
 	}
 
@@ -891,11 +921,35 @@
 
 		switch (pa->type) {
 		case ISAKMP_NPTYPE_VID:
-			vid_numeric = handle_vendorid(iph1, pa->ptr);
+			vid_numeric = check_vendorid(pa->ptr);
+#ifdef ENABLE_NATT
+			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
+				natt_handle_vendorid(iph1, vid_numeric);
+#endif
 #ifdef ENABLE_FRAG
 			if ((vid_numeric == VENDORID_FRAG) &&
 			    (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT))
 				iph1->frag = 1;
+#endif   
+#ifdef ENABLE_HYBRID
+			switch (vid_numeric) {
+			case VENDORID_XAUTH:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_XAUTH;
+				break;
+		
+			case VENDORID_UNITY:
+				iph1->mode_cfg->flags |=
+				    ISAKMP_CFG_VENDORID_UNITY;
+				break;
+	
+			default:  
+				break;
+			}
+#endif
+#ifdef ENABLE_DPD
+			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
+				iph1->dpd_support=1;
 #endif
 			break;
 		default:
@@ -967,13 +1021,13 @@
 #ifdef ENABLE_HYBRID
         vchar_t *vid_xauth = NULL;
         vchar_t *vid_unity = NULL;
-#endif
+#endif  
 #ifdef ENABLE_DPD
 	vchar_t *vid_dpd = NULL;
 #endif
-#ifdef ENABLE_FRAG
+#ifdef ENABLE_FRAG          
 	vchar_t *vid_frag = NULL;
-#endif
+#endif 
 
 	/* validity check */
 	if (iph1->status != PHASE1ST_MSG1RECEIVED) {
@@ -987,10 +1041,10 @@
 
 #ifdef HAVE_GSSAPI
 	if (iph1->approval->gssid != NULL) {
-		gss_sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->approval);
+		gss_sa = ipsecdoi_setph1proposal(iph1->approval);
 		if (gss_sa != iph1->sa_ret)
 			free_gss_sa = 1;
-	} else
+	} else 
 #endif
 		gss_sa = iph1->sa_ret;
 
@@ -1028,7 +1082,8 @@
 		plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
 #endif
 #ifdef ENABLE_DPD
-	if (iph1->dpd_support) {
+	/* XXX only send DPD VID if remote sent it ? */
+	if(iph1->rmconf->dpd){
 		vid_dpd = set_vendorid(VENDORID_DPD);
 		if (vid_dpd != NULL)
 			plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
@@ -1044,7 +1099,7 @@
 			plog(LLV_ERROR, LOCATION, NULL,
 			    "Frag vendorID construction failed\n");
 		else
-			plist = isakmp_plist_append(plist,
+			plist = isakmp_plist_append(plist, 
 			     vid_frag, ISAKMP_NPTYPE_VID);
 	}
 #endif
@@ -1056,8 +1111,10 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1) {
 		goto end;
+	}
 
 	/* the sending message is added to the received-list. */
 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
@@ -1146,7 +1203,7 @@
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 		case ISAKMP_NPTYPE_CR:
 			plog(LLV_WARNING, LOCATION, iph1->remote,
@@ -1169,20 +1226,20 @@
 			{
 				vchar_t *natd_received = NULL;
 				int natd_verified;
-
+				
 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
 					goto end;
-
+				
 				if (natd_seq == 0)
 					iph1->natt_flags |= NAT_DETECTED;
-
+				
 				natd_verified = natt_compare_addr_hash (iph1,
 					natd_received, natd_seq++);
-
+				
 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
 					natd_seq - 1,
 					natd_verified ? "verified" : "doesn't match");
-
+				
 				vfree (natd_received);
 				break;
 			}
@@ -1202,7 +1259,7 @@
 #ifdef ENABLE_NATT
 	if (NATT_AVAILABLE(iph1))
 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
-		      iph1->natt_flags & NAT_DETECTED ?
+		      iph1->natt_flags & NAT_DETECTED ? 
 		      		"detected:" : "not detected",
 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
@@ -1264,12 +1321,12 @@
 		goto end;
 
 	/* generate NONCE value */
-	iph1->nonce = eay_set_random(RMCONF_NONCE_SIZE(iph1->rmconf));
+	iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
 	if (iph1->nonce == NULL)
 		goto end;
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
 		gssapi_get_rtoken(iph1, NULL);
 #endif
 
@@ -1283,7 +1340,8 @@
 #endif
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph1send(iph1) == -1)
+	iph1->retry_counter = iph1->rmconf->retry_counter;
+	if (isakmp_ph1resend(iph1) == -1)
 		goto end;
 
 	/* the sending message is added to the received-list. */
@@ -1371,8 +1429,6 @@
 		case ISAKMP_NPTYPE_ID:
 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
 				goto end;
-			if (resolveph1rmconf(iph1) < 0)
-				goto end;
 			break;
 		case ISAKMP_NPTYPE_HASH:
 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
@@ -1397,10 +1453,10 @@
 			break;
 #endif
 		case ISAKMP_NPTYPE_VID:
-			handle_vendorid(iph1, pa->ptr);
+			(void)check_vendorid(pa->ptr);
 			break;
 		case ISAKMP_NPTYPE_N:
-			ident_recv_n(iph1, pa->ptr);
+			isakmp_check_notify(pa->ptr, iph1);
 			break;
 		default:
 			/* don't send information, see ident_r1recv() */
@@ -1417,7 +1473,7 @@
     {
 	int ng = 0;
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
@@ -1481,7 +1537,8 @@
 				/* msg printed inner oakley_validate_auth() */
 				goto end;
 			}
-			evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
+			EVT_PUSH(iph1->local, iph1->remote, 
+			    EVTT_PEERPH1AUTH_FAILED, NULL);
 			isakmp_info_send_n1(iph1, type, NULL);
 			goto end;
 		}
@@ -1526,10 +1583,13 @@
 
 	if (error) {
 		VPTRINIT(iph1->id_p);
-		VPTRINIT(iph1->cert_p);
-		VPTRINIT(iph1->crl_p);
+		oakley_delcert(iph1->cert_p);
+		iph1->cert_p = NULL;
+		oakley_delcert(iph1->crl_p);
+		iph1->crl_p = NULL;
 		VPTRINIT(iph1->sig_p);
-		VPTRINIT(iph1->cr_p);
+		oakley_delcert(iph1->cr_p);
+		iph1->cr_p = NULL;
 	}
 
 	return error;
@@ -1566,7 +1626,7 @@
 		goto end;
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
 	    gssapi_more_tokens(iph1)) {
 		gssapi_get_rtoken(iph1, &len);
 		if (len != 0)
@@ -1634,6 +1694,8 @@
 {
 	vchar_t *buf = 0;
 	struct payload_list *plist = NULL;
+	int need_cr = 0;
+	vchar_t *cr = NULL;
 	vchar_t *vid = NULL;
 	int error = -1;
 #ifdef HAVE_GSSAPI
@@ -1643,14 +1705,23 @@
 	vchar_t *natd[2] = { NULL, NULL };
 #endif
 
-#ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
-		if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
+	/* create CR if need */
+	if (iph1->side == RESPONDER
+	 && iph1->rmconf->send_cr
+	 && oakley_needcr(iph1->approval->authmethod)
+	 && iph1->rmconf->peerscertfile == NULL) {
+		need_cr = 1;
+		cr = oakley_getcr(iph1);
+		if (cr == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			     "Failed to get gssapi token.\n");
+				"failed to get cr buffer.\n");
 			goto end;
 		}
 	}
+
+#ifdef HAVE_GSSAPI
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+		gssapi_get_token_to_send(iph1, &gsstoken);
 #endif
 
 	/* create isakmp KE payload */
@@ -1660,7 +1731,7 @@
 	plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
 		plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
 #endif
 
@@ -1668,10 +1739,9 @@
 	if (vid)
 		plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
 
-	/* create CR if need */
-	if (iph1->side == RESPONDER &&
-	    oakley_needcr(iph1->approval->authmethod))
-		plist = oakley_append_cr(plist, iph1);
+	/* create isakmp CR payload if needed */
+	if (need_cr)
+		plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
 
 #ifdef ENABLE_NATT
 	/* generate and append NAT-D payloads */
@@ -1694,9 +1764,9 @@
 		plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
 	}
 #endif
-
+	
 	buf = isakmp_plist_set_all (&plist, iph1);
-
+	
 	error = 0;
 
 end:
@@ -1704,6 +1774,8 @@
 		vfree(buf);
 		buf = NULL;
 	}
+	if (cr)
+		vfree(cr);
 #ifdef HAVE_GSSAPI
 	if (gsstoken)
 		vfree(gsstoken);
@@ -1742,7 +1814,9 @@
 {
 	struct payload_list *plist = NULL;
 	vchar_t *buf = NULL, *new = NULL;
+	int need_cr = 0;
 	int need_cert = 0;
+	vchar_t *cr = NULL;
 	int error = -1;
 #ifdef HAVE_GSSAPI
 	int nptype;
@@ -1750,10 +1824,10 @@
 	vchar_t *gsshash = NULL;
 #endif
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
@@ -1773,13 +1847,27 @@
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-#endif
+#endif 
 		if (oakley_getmycert(iph1) < 0)
 			goto end;
 
 		if (oakley_getsign(iph1) < 0)
 			goto end;
 
+		/* create CR if need */
+		if (iph1->side == INITIATOR
+		 && iph1->rmconf->send_cr
+	 	 && oakley_needcr(iph1->approval->authmethod)
+		 && iph1->rmconf->peerscertfile == NULL) {
+			need_cr = 1;
+			cr = oakley_getcr(iph1);
+			if (cr == NULL) {
+				plog(LLV_ERROR, LOCATION, NULL,
+					"failed to get cr buffer.\n");
+				goto end;
+			}
+		}
+
 		if (iph1->cert != NULL && iph1->rmconf->send_cert)
 			need_cert = 1;
 
@@ -1788,15 +1876,13 @@
 
 		/* add CERT payload if there */
 		if (need_cert)
-			plist = isakmp_plist_append(plist, iph1->cert,
-						    ISAKMP_NPTYPE_CERT);
+			plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 		/* add SIG payload */
 		plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
 
 		/* create isakmp CR payload */
-		if (iph1->side == INITIATOR &&
-		    oakley_needcr(iph1->approval->authmethod))
-			plist = oakley_append_cr(plist, iph1);
+		if (need_cr)
+			plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
 		break;
 #ifdef HAVE_GSSAPI
 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
@@ -1805,11 +1891,7 @@
 			if (gsshash == NULL)
 				goto end;
 		} else {
-			if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
-				plog(LLV_ERROR, LOCATION, NULL,
-					"Failed to get gssapi token.\n");
-				goto end;
-			}
+			gssapi_get_token_to_send(iph1, &gsstoken);
 		}
 
 		if (!gssapi_id_sent(iph1)) {
@@ -1845,7 +1927,7 @@
 	}
 
 	buf = isakmp_plist_set_all (&plist, iph1);
-
+	
 #ifdef HAVE_PRINT_ISAKMP_C
 	isakmp_printpacket(buf, iph1->local, iph1->remote, 1);
 #endif
@@ -1866,6 +1948,8 @@
 	if (gsstoken)
 		vfree(gsstoken);
 #endif
+	if (cr)
+		vfree(cr);
 	if (error && buf != NULL) {
 		vfree(buf);
 		buf = NULL;
@@ -1873,28 +1957,3 @@
 
 	return buf;
 }
-
-/*
- * handle a notification payload inside identity exchange.
- * called only when the packet has been verified to be encrypted.
- */
-static int
-ident_recv_n(iph1, gen)
-	struct ph1handle *iph1;
-	struct isakmp_gen *gen;
-{
-	struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen;
-	u_int type;
-
-	type = ntohs(notify->type);
-	switch (type) {
-	case ISAKMP_NTYPE_INITIAL_CONTACT:
-		iph1->initial_contact_received = TRUE;
-		break;
-	default:
-		isakmp_log_notify(iph1, notify, "identity exchange");
-		break;
-	}
-	return 0;
-}
-
diff --git a/src/racoon/isakmp_inf.c b/src/racoon/isakmp_inf.c
index 9bf81c6..5f487d2 100644
--- a/src/racoon/isakmp_inf.c
+++ b/src/racoon/isakmp_inf.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_inf.c,v 1.47 2011/03/15 13:20:14 vanhu Exp $	*/
+/*	$NetBSD: isakmp_inf.c,v 1.14.4.17 2009/05/18 17:07:46 tteras Exp $	*/
 
 /* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
 
@@ -107,10 +107,11 @@
 	struct isakmp_pl_ru *, u_int32_t));
 static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
 	struct isakmp_pl_ru *, u_int32_t));
-static void isakmp_info_send_r_u __P((struct sched *));
+static void isakmp_info_send_r_u __P((void *));
 #endif
 
 static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
+static void info_recv_initialcontact __P((struct ph1handle *));
 
 /* %%%
  * Information Exchange
@@ -167,8 +168,7 @@
 	if (msg->l < sizeof(*isakmp) + sizeof(*gen)) {
 		plog(LLV_ERROR, LOCATION, NULL, 
 			"ignore information because the "
-			"message is way too short - %zu byte(s).\n",
-			msg->l);
+			"message is way too short - %zu byte(s).\n", msg->l);
 		goto end;
 	}
 
@@ -179,15 +179,14 @@
 	if (encrypted) {
 		if (isakmp->np != ISAKMP_NPTYPE_HASH) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			    "ignore information because the "
+			    "ignore information because the"
 			    "message has no hash payload.\n");
 			goto end;
 		}
 
-		if (iph1->status != PHASE1ST_ESTABLISHED &&
-		    iph1->status != PHASE1ST_DYING) {
+		if (iph1->status != PHASE1ST_ESTABLISHED) {
 			plog(LLV_ERROR, LOCATION, NULL,
-			    "ignore information because ISAKMP-SA "
+			    "ignore information because ISAKMP-SA"
 			    "has not been established yet.\n");
 			goto end;
 		}
@@ -196,8 +195,7 @@
 		if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) {
 			plog(LLV_ERROR, LOCATION, NULL, 
 				"ignore information because the "
-				"message is too short - %zu byte(s).\n",
-				msg->l);
+				"message is too short - %zu byte(s).\n", msg->l);
 			goto end;
 		}
 
@@ -325,65 +323,6 @@
 	return error;
 }
 
-
-/*
- * log unhandled / unallowed Notification payload
- */
-int
-isakmp_log_notify(iph1, notify, exchange)
-	struct ph1handle *iph1;
-	struct isakmp_pl_n *notify;
-	const char *exchange;
-{
-	u_int type;
-	char *nraw, *ndata, *nhex;
-	size_t l;
-
-	type = ntohs(notify->type);
-	if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
-		plog(LLV_ERROR, LOCATION, iph1->remote,
-			"invalid spi_size in %s notification in %s.\n",
-			s_isakmp_notify_msg(type), exchange);
-		return -1;
-	}
-
-	plog(LLV_ERROR, LOCATION, iph1->remote,
-		"notification %s received in %s.\n",
-		s_isakmp_notify_msg(type), exchange);
-
-	nraw = ((char*) notify) + sizeof(*notify) + notify->spi_size;
-	l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
-	if (l > 0) {
-		if (type >= ISAKMP_NTYPE_MINERROR &&
-		    type <= ISAKMP_NTYPE_MAXERROR) {
-			ndata = binsanitize(nraw, l);
-			if (ndata != NULL) {
-				plog(LLV_ERROR, LOCATION, iph1->remote,
-					"error message: '%s'.\n",
-					ndata);
-				racoon_free(ndata);
-			} else {
-				plog(LLV_ERROR, LOCATION, iph1->remote,
-					"Cannot allocate memory\n");
-			}
-		} else {
-			nhex = val2str(nraw, l);
-			if (nhex != NULL) {
-				plog(LLV_ERROR, LOCATION, iph1->remote,
-					"notification payload: %s.\n",
-					nhex);
-				racoon_free(nhex);
-			} else {
-				plog(LLV_ERROR, LOCATION, iph1->remote,
-					"Cannot allocate memory\n");
-			}
-		}
-	}
-
-	return 0;
-}
-
-
 /*
  * handling of Notification payload
  */
@@ -395,8 +334,13 @@
 	int encrypted;
 {
 	u_int type;
+	vchar_t *pbuf;
+	char *nraw, *ndata;
+	size_t l;
+	char *spi;
 
 	type = ntohs(notify->type);
+
 	switch (type) {
 	case ISAKMP_NTYPE_CONNECTED:
 	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
@@ -408,7 +352,8 @@
 		break;
 	case ISAKMP_NTYPE_INITIAL_CONTACT:
 		if (encrypted)
-			return isakmp_info_recv_initialcontact(iph1, NULL);
+			info_recv_initialcontact(iph1);
+			return 0;
 		break;
 #ifdef ENABLE_DPD
 	case ISAKMP_NTYPE_R_U_THERE:
@@ -422,23 +367,76 @@
 				(struct isakmp_pl_ru *)notify, msgid);
 		break;
 #endif
+	default:
+	    {
+		/* XXX there is a potential of dos attack. */
+		if(type >= ISAKMP_NTYPE_MINERROR &&
+		   type <= ISAKMP_NTYPE_MAXERROR) {
+			if (msgid == 0) {
+				/* don't think this realy deletes ph1 ? */
+				plog(LLV_ERROR, LOCATION, iph1->remote,
+					"delete phase1 handle.\n");
+				return -1;
+			} else {
+				if (getph2bymsgid(iph1, msgid) == NULL) {
+					plog(LLV_ERROR, LOCATION, iph1->remote,
+						"fatal %s notify messsage, "
+						"phase1 should be deleted.\n",
+						s_isakmp_notify_msg(type));
+				} else {
+					plog(LLV_ERROR, LOCATION, iph1->remote,
+						"fatal %s notify messsage, "
+						"phase2 should be deleted.\n",
+						s_isakmp_notify_msg(type));
+				}
+			}
+		} else {
+			plog(LLV_ERROR, LOCATION, iph1->remote,
+				"unhandled notify message %s, "
+				"no phase2 handle found.\n",
+				s_isakmp_notify_msg(type));
+		}
+	    }
+	    break;
 	}
 
-	/* If we receive a error notification we should delete the related
-	 * phase1 / phase2 handle, and send an event to racoonctl.
-	 * However, since phase1 error notifications are not encrypted and
-	 * can not be authenticated, it would allow a DoS attack possibility
-	 * to handle them.
-	 * Phase2 error notifications should be encrypted, so we could handle
-	 * those, but it needs implementing (the old code didn't implement
-	 * that either).
-	 * So we are good to just log the messages here.
-	 */
-	if (encrypted)
-		isakmp_log_notify(iph1, notify, "informational exchange");
-	else
-		isakmp_log_notify(iph1, notify, "unencrypted informational exchange");
+	/* get spi if specified and allocate */
+	if(notify->spi_size > 0) {
+		if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) {
+			plog(LLV_ERROR, LOCATION, iph1->remote,
+				"invalid spi_size in notification payload.\n");
+			return -1;
+		}
+		spi = val2str((char *)(notify + 1), notify->spi_size);
 
+		plog(LLV_DEBUG, LOCATION, iph1->remote,
+			"notification message %d:%s, "
+			"doi=%d proto_id=%d spi=%s(size=%d).\n",
+			type, s_isakmp_notify_msg(type),
+			ntohl(notify->doi), notify->proto_id, spi, notify->spi_size);
+
+		racoon_free(spi);
+	}
+
+	/* Send the message data to the logs */
+	if(type >= ISAKMP_NTYPE_MINERROR &&
+	   type <= ISAKMP_NTYPE_MAXERROR) {
+		l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
+		if (l > 0) {
+			nraw = (char*)notify;	
+			nraw += sizeof(*notify) + notify->spi_size;
+			ndata = binsanitize(nraw, l);
+			if (ndata != NULL) {
+				plog(LLV_ERROR, LOCATION, iph1->remote,
+				    "Message: '%s'.\n", 
+				    ndata);
+				racoon_free(ndata);
+			} else {
+				plog(LLV_ERROR, LOCATION, iph1->remote,
+				    "Cannot allocate memory\n");
+			}
+		}
+	}
 	return 0;
 }
 
@@ -512,16 +510,16 @@
 		del_ph1=getph1byindex((isakmp_index *)(delete + 1));
 		if(del_ph1 != NULL){
 
-			evt_phase1(iph1, EVT_PHASE1_PEER_DELETED, NULL);
-			sched_cancel(&del_ph1->scr);
+			EVT_PUSH(del_ph1->local, del_ph1->remote,
+			EVTT_PEERPH1_NOPROP, NULL);
+			if (del_ph1->scr)
+				SCHED_KILL(del_ph1->scr);
 
 			/*
-			 * Delete also IPsec-SAs if rekeying is enabled.
+			 * Do not delete IPsec SAs when receiving an IKE delete notification.
+			 * Just delete the IKE SA.
 			 */
-			if (ph1_rekey_enabled(del_ph1))
-				purge_remote(del_ph1);
-			else
-				isakmp_ph1expire(del_ph1);
+			isakmp_ph1expire(del_ph1);
 		}
 		break;
 
@@ -534,6 +532,8 @@
 				delete->spi_size, delete->proto_id);
 			return 0;
 		}
+		EVT_PUSH(iph1->local, iph1->remote, 
+		    EVTT_PEER_DELETE, NULL);
 		purge_ipsec_spi(iph1->remote, delete->proto_id,
 		    (u_int32_t *)(delete + 1), num_spi);
 		break;
@@ -636,7 +636,7 @@
 	 * don't send delete information if there is no phase 1 handler.
 	 * It's nonsensical to negotiate phase 1 to send the information.
 	 */
-	iph1 = getph1byaddr(iph2->src, iph2->dst, 0); 
+	iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
 	if (iph1 == NULL){
 		plog(LLV_DEBUG2, LOCATION, NULL,
 			 "No ph1 handler found, could not send DELETE_SA\n");
@@ -696,12 +696,21 @@
 	vchar_t *data;
 {
 	struct ph1handle *iph1 = NULL;
+	struct remoteconf *rmconf;
 	vchar_t *payload = NULL;
 	int tlen;
 	int error = -1;
 	struct isakmp_pl_n *n;
 	int spisiz = 0;		/* see below */
 
+	/* search appropreate configuration */
+	rmconf = getrmconf(remote);
+	if (rmconf == NULL) {
+		plog(LLV_ERROR, LOCATION, remote,
+			"no configuration found for peer address.\n");
+		goto end;
+	}
+
 	/* add new entry to isakmp status table. */
 	iph1 = newph1();
 	if (iph1 == NULL)
@@ -710,6 +719,7 @@
 	memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
 	isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
 	iph1->status = PHASE1ST_START;
+	iph1->rmconf = rmconf;
 	iph1->side = INITIATOR;
 	iph1->version = isakmp->v;
 	iph1->flags = 0;
@@ -724,7 +734,7 @@
 #endif
 
 	/* copy remote address */
-	if (copy_ph1addresses(iph1, NULL, remote, local) < 0)
+	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0)
 		goto end;
 
 	tlen = sizeof(*n) + spisiz;
@@ -901,6 +911,16 @@
 		delph2(iph2);
 		goto end;
 	}
+#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
+	if (set_port(iph2->dst, 0) == NULL ||
+	    set_port(iph2->src, 0) == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+		     "invalid family: %d\n", iph1->remote->sa_family);
+		delph2(iph2);
+		goto end;
+	}
+#endif
+	iph2->ph1 = iph1;
 	iph2->side = INITIATOR;
 	iph2->status = PHASE2ST_START;
 	iph2->msgid = isakmp_newmsgid2(iph1);
@@ -914,7 +934,7 @@
 		}
 
 		/* generate HASH(1) */
-		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
+		hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
 		if (hash == NULL) {
 			delph2(iph2);
 			goto end;
@@ -1015,6 +1035,7 @@
 	return error;
 
 err:
+	unbindph12(iph2);
 	remph2(iph2);
 	delph2(iph2);
 	goto end;
@@ -1093,8 +1114,9 @@
 			s_ipsecdoi_proto(proto),
 			isakmp_pindex(&spi[i], 0));
 
+		SCHED_KILL(iph1->sce);
 		iph1->status = PHASE1ST_EXPIRED;
-		isakmp_ph1delete(iph1);
+		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 	}
 }
 
@@ -1116,6 +1138,10 @@
 	u_int64_t created;
 	size_t i;
 	caddr_t mhp[SADB_EXT_MAX + 1];
+#ifdef ENABLE_NATT
+	struct sadb_x_nat_t_type *natt_type;
+	struct sadb_x_nat_t_port *natt_port;
+#endif
 
 	plog(LLV_DEBUG2, LOCATION, NULL,
 		 "purge_ipsec_spi:\n");
@@ -1155,7 +1181,6 @@
 			msg = next;
 			continue;
 		}
-		pk_fixup_sa_addresses(mhp);
 		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 		lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
@@ -1169,7 +1194,25 @@
 			msg = next;
 			continue;
 		}
+#ifdef ENABLE_NATT
+		natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
+		if (natt_type && natt_type->sadb_x_nat_t_type_type) {
+			/* NAT-T is enabled for this SADB entry; copy
+			 * the ports from NAT-T extensions */
+			natt_port = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
+			if (extract_port(src) == 0 && natt_port != NULL)
+				set_port(src, ntohs(natt_port->sadb_x_nat_t_port_port));
 
+			natt_port = (void *)mhp[SADB_X_EXT_NAT_T_DPORT];
+			if (extract_port(dst) == 0 && natt_port != NULL)
+				set_port(dst, ntohs(natt_port->sadb_x_nat_t_port_port));
+		}else{
+			/* Force default UDP ports, so CMPSADDR will match SAs with NO encapsulation
+			 */
+			set_port(src, PORT_ISAKMP);
+			set_port(dst, PORT_ISAKMP);
+		}
+#endif
 		plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
 		plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst));
 
@@ -1177,11 +1220,20 @@
 
 		/* don't delete inbound SAs at the moment */
 		/* XXX should we remove SAs with opposite direction as well? */
-		if (cmpsaddr(dst0, dst) != CMPSADDR_MATCH) {
+		if (CMPSADDR(dst0, dst)) {
 			msg = next;
 			continue;
 		}
 
+#ifdef ENABLE_NATT
+		if (natt_type == NULL ||
+			! natt_type->sadb_x_nat_t_type_type) {
+			/* Set back port to 0 if it was forced to default UDP port
+			 */
+			set_port(src, 0);
+			set_port(dst, 0);
+		}
+#endif
 		for (i = 0; i < n; i++) {
 			plog(LLV_DEBUG, LOCATION, NULL,
 				"check spi(packet)=%u spi(db)=%u.\n",
@@ -1202,6 +1254,7 @@
 			iph2 = getph2bysaidx(src, dst, proto, spi[i]);
 			if(iph2 != NULL){
 				delete_spd(iph2, created);
+				unbindph12(iph2);
 				remph2(iph2);
 				delph2(iph2);
 			}
@@ -1220,17 +1273,15 @@
 }
 
 /*
- * delete all phase2 sa relatived to the destination address
- * (except the phase2 within which the INITIAL-CONTACT was received).
+ * delete all phase2 sa relatived to the destination address.
  * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
  * an INITIAL-CONTACT if we have contacted the peer.  This matches the
  * Sun IKE behavior, and makes rekeying work much better when the peer
  * restarts.
  */
-int
-isakmp_info_recv_initialcontact(iph1, protectedph2)
+static void
+info_recv_initialcontact(iph1)
 	struct ph1handle *iph1;
-	struct ph2handle *protectedph2;
 {
 	vchar_t *buf = NULL;
 	struct sadb_msg *msg, *next, *end;
@@ -1243,10 +1294,8 @@
 	char *loc, *rem;
 #endif
 
-	plog(LLV_INFO, LOCATION, iph1->remote, "received INITIAL-CONTACT\n");
-
 	if (f_local)
-		return 0;
+		return;
 
 #if 0
 	loc = racoon_strdup(saddrwop2str(iph1->local));
@@ -1295,7 +1344,7 @@
 
 	racoon_free(loc);
 	racoon_free(rem);
-	return 0;
+	return;
 
  the_hard_way:
 	racoon_free(loc);
@@ -1306,39 +1355,43 @@
 	if (buf == NULL) {
 		plog(LLV_DEBUG, LOCATION, NULL,
 			"pfkey_dump_sadb returned nothing.\n");
-		return 0;
+		return;
 	}
 
 	msg = (struct sadb_msg *)buf->v;
 	end = (struct sadb_msg *)(buf->v + buf->l);
 
-	for (; msg < end; msg = next) {
+	while (msg < end) {
 		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
 			break;
-
 		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
-		if (msg->sadb_msg_type != SADB_DUMP)
+		if (msg->sadb_msg_type != SADB_DUMP) {
+			msg = next;
 			continue;
+		}
 
 		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"pfkey_check (%s)\n", ipsec_strerror());
+			msg = next;
 			continue;
 		}
 
 		if (mhp[SADB_EXT_SA] == NULL
 		 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
-		 || mhp[SADB_EXT_ADDRESS_DST] == NULL)
+		 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
+			msg = next;
 			continue;
-
+		}
 		sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
-		pk_fixup_sa_addresses(mhp);
 		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
 		if (sa->sadb_sa_state != SADB_SASTATE_MATURE
-		 && sa->sadb_sa_state != SADB_SASTATE_DYING)
+		 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
+			msg = next;
 			continue;
+		}
 
 		/*
 		 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
@@ -1348,18 +1401,39 @@
 		 * racoon only deletes SA which is matched both the
 		 * source address and the destination accress.
 		 */
-
-		/*
-		 * Check that the IP and port match. But this is not optimal,
-		 * since NAT-T can make the peer have multiple different
-		 * ports. Correct thing to do is delete all entries with
-                 * same identity. -TT
-                 */
-		if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH ||
-		     cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) &&
-		    (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH ||
-		     cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH))
+#ifdef ENABLE_NATT
+		/* 
+		 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs
+		 * from this peer !
+		 */
+		if(iph1->natt_flags & NAT_DETECTED){
+			if (CMPSADDR(iph1->local, src) == 0 &&
+				CMPSADDR(iph1->remote, dst) == 0)
+				;
+			else if (CMPSADDR(iph1->remote, src) == 0 &&
+					 CMPSADDR(iph1->local, dst) == 0)
+				;
+			else {
+				msg = next;
+				continue;
+			}
+		} else
+#endif
+		/* If there is no NAT-T, we don't have to check addr + port...
+		 * XXX what about a configuration with a remote peers which is not
+		 * NATed, but which NATs some other peers ?
+		 * Here, the INITIAl-CONTACT would also flush all those NATed peers !!
+		 */
+		if (cmpsaddrwop(iph1->local, src) == 0 &&
+		    cmpsaddrwop(iph1->remote, dst) == 0)
+			;
+		else if (cmpsaddrwop(iph1->remote, src) == 0 &&
+		    cmpsaddrwop(iph1->local, dst) == 0)
+			;
+		else {
+			msg = next;
 			continue;
+		}
 
 		/*
 		 * Make sure this is an SATYPE that we manage.
@@ -1371,8 +1445,10 @@
 			    msg->sadb_msg_satype)
 				break;
 		}
-		if (i == pfkey_nsatypes)
+		if (i == pfkey_nsatypes) {
+			msg = next;
 			continue;
+		}
 
 		plog(LLV_INFO, LOCATION, NULL,
 			"purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
@@ -1387,15 +1463,54 @@
 		 */
 		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
 		iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
-		if (iph2 && iph2 != protectedph2) {
+		if (iph2) {
 			delete_spd(iph2, 0);
+			unbindph12(iph2);
 			remph2(iph2);
 			delph2(iph2);
 		}
+
+		msg = next;
 	}
 
 	vfree(buf);
-	return 0;
+}
+
+void
+isakmp_check_notify(gen, iph1)
+	struct isakmp_gen *gen;		/* points to Notify payload */
+	struct ph1handle *iph1;
+{
+	struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
+
+	plog(LLV_DEBUG, LOCATION, iph1->remote,
+		"Notify Message received\n");
+
+	switch (ntohs(notify->type)) {
+	case ISAKMP_NTYPE_CONNECTED:
+	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
+	case ISAKMP_NTYPE_REPLAY_STATUS:
+	case ISAKMP_NTYPE_HEARTBEAT:
+#ifdef ENABLE_HYBRID
+	case ISAKMP_NTYPE_UNITY_HEARTBEAT:
+#endif
+		plog(LLV_WARNING, LOCATION, iph1->remote,
+			"ignore %s notification.\n",
+			s_isakmp_notify_msg(ntohs(notify->type)));
+		break;
+	case ISAKMP_NTYPE_INITIAL_CONTACT:
+		plog(LLV_WARNING, LOCATION, iph1->remote,
+			"ignore INITIAL-CONTACT notification, "
+			"because it is only accepted after phase1.\n");
+		break;
+	default:
+		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
+		plog(LLV_ERROR, LOCATION, iph1->remote,
+			"received unknown notification type %s.\n",
+			s_isakmp_notify_msg(ntohs(notify->type)));
+	}
+
+	return;
 }
 
 
@@ -1452,16 +1567,17 @@
 	struct isakmp_pl_ru *ru;
 	u_int32_t msgid;
 {
-	u_int32_t seq;
 
 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 		 "DPD R-U-There-Ack received\n");
 
-	seq = ntohl(ru->data);
-	if (seq <= iph1->dpd_last_ack || seq > iph1->dpd_seq) {
+	/* XXX Maintain window of acceptable sequence numbers ?
+	 * => ru->data <= iph2->dpd_seq &&
+	 *    ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
+	if (ntohl(ru->data) != iph1->dpd_seq-1) {
 		plog(LLV_ERROR, LOCATION, iph1->remote,
-			 "Wrong DPD sequence number (%d; last_ack=%d, seq=%d).\n", 
-			 seq, iph1->dpd_last_ack, iph1->dpd_seq);
+			 "Wrong DPD sequence number (%d, %d expected).\n", 
+			 ntohl(ru->data), iph1->dpd_seq-1);
 		return 0;
 	}
 
@@ -1473,8 +1589,12 @@
 	}
 
 	iph1->dpd_fails = 0;
-	iph1->dpd_last_ack = seq;
-	sched_cancel(&iph1->dpd_r_u);
+
+	/* Useless ??? */
+	iph1->dpd_lastack = time(NULL);
+
+	SCHED_KILL(iph1->dpd_r_u);
+
 	isakmp_sched_r_u(iph1, 0);
 
 	plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
@@ -1489,10 +1609,10 @@
  * send DPD R-U-THERE payload in Informational exchange.
  */
 static void
-isakmp_info_send_r_u(sc)
-	struct sched *sc;
+isakmp_info_send_r_u(arg)
+	void *arg;
 {
-	struct ph1handle *iph1 = container_of(sc, struct ph1handle, dpd_r_u);
+	struct ph1handle *iph1 = arg;
 
 	/* create R-U-THERE payload */
 	struct isakmp_pl_ru *ru;
@@ -1502,14 +1622,7 @@
 
 	plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
 
-	if (iph1->status == PHASE1ST_EXPIRED) {
-		/* This can happen after removing tunnels from the
-		 * config file and then reloading.
-		 * Such iph1 have rmconf=NULL, so return before the if
-		 * block below.
-		 */
-		return;
-	}
+	iph1->dpd_r_u=NULL;
 
 	if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
 
@@ -1517,8 +1630,7 @@
 			"DPD: remote (ISAKMP-SA spi=%s) seems to be dead.\n",
 			isakmp_pindex(&iph1->index, 0));
 
-		script_hook(iph1, SCRIPT_PHASE1_DEAD);
-		evt_phase1(iph1, EVT_PHASE1_DPD_TIMEOUT, NULL);
+		EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL);
 		purge_remote(iph1);
 
 		/* Do not reschedule here: phase1 is deleted,
@@ -1547,13 +1659,12 @@
 	memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
 	memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
 
-	if (iph1->dpd_seq == 0) {
+	if (iph1->dpd_seq == 0){
 		/* generate a random seq which is not too big */
-		iph1->dpd_seq = iph1->dpd_last_ack = rand() & 0x0fff;
+		srand(time(NULL));
+		iph1->dpd_seq = rand() & 0x0fff;
 	}
 
-	iph1->dpd_seq++;
-	iph1->dpd_fails++;
 	ru->data = htonl(iph1->dpd_seq);
 
 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
@@ -1562,6 +1673,12 @@
 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 		 "DPD R-U-There sent (%d)\n", error);
 
+	/* will be decreased if ACK received... */
+	iph1->dpd_fails++;
+
+	/* XXX should be increased only when ACKed ? */
+	iph1->dpd_seq++;
+
 	/* Reschedule the r_u_there with a short delay,
 	 * will be deleted/rescheduled if ACK received before */
 	isakmp_sched_r_u(iph1, 1);
@@ -1586,11 +1703,11 @@
 		return 0;
 
 	if(retry)
-		sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_retry,
-			       isakmp_info_send_r_u);
+		iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
+								  isakmp_info_send_r_u, iph1);
 	else
-		sched_schedule(&iph1->dpd_r_u, iph1->rmconf->dpd_interval,
-			       isakmp_info_send_r_u);
+		iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval,
+								  isakmp_info_send_r_u, iph1);
 
 	return 0;
 }
diff --git a/src/racoon/isakmp_inf.h b/src/racoon/isakmp_inf.h
index 40cdc02..c7682d9 100644
--- a/src/racoon/isakmp_inf.h
+++ b/src/racoon/isakmp_inf.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_inf.h,v 1.5 2008/07/14 05:40:13 tteras Exp $	*/
+/*	$NetBSD: isakmp_inf.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: isakmp_inf.h,v 1.6 2005/05/07 14:15:59 manubsd Exp */
 
@@ -48,8 +48,7 @@
 extern vchar_t * isakmp_add_pl_n __P((vchar_t *, u_int8_t **, int,
 	struct saproto *, vchar_t *));
 
-extern int isakmp_log_notify __P((struct ph1handle *, struct isakmp_pl_n *, const char *exchange));
-extern int isakmp_info_recv_initialcontact __P((struct ph1handle *, struct ph2handle *));
+extern void isakmp_check_notify __P((struct isakmp_gen *, struct ph1handle *));
 
 #ifdef ENABLE_DPD
 extern int isakmp_sched_r_u __P((struct ph1handle *, int));
diff --git a/src/racoon/isakmp_quick.c b/src/racoon/isakmp_quick.c
index 65a83a3..963438d 100644
--- a/src/racoon/isakmp_quick.c
+++ b/src/racoon/isakmp_quick.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_quick.c,v 1.29 2011/03/14 17:18:13 tteras Exp $	*/
+/*	$NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $	*/
 
 /* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */
 
@@ -53,6 +53,9 @@
 #  include <time.h>
 # endif
 #endif
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#endif
 
 #include PATH_IPSEC_H
 
@@ -84,47 +87,10 @@
 #include "admin.h"
 #include "strnames.h"
 
-#ifdef ENABLE_HYBRID
-#include <resolv.h>
-#include "isakmp_xauth.h"
-#include "isakmp_cfg.h"
-#endif
-
-#ifdef ENABLE_NATT
-#include "nattraversal.h"
-#endif
-
 /* quick mode */
 static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
 static int get_sainfo_r __P((struct ph2handle *));
 static int get_proposal_r __P((struct ph2handle *));
-static int ph2_recv_n __P((struct ph2handle *, struct isakmp_gen *));
-static void quick_timeover_stub __P((struct sched *));
-static void quick_timeover __P((struct ph2handle *));
-
-/* called from scheduler */
-static void
-quick_timeover_stub(p)
-	struct sched *p;
-{
-	quick_timeover(container_of(p, struct ph2handle, sce));
-}
-
-static void
-quick_timeover(iph2)
-	struct ph2handle *iph2;
-{
-	plog(LLV_ERROR, LOCATION, NULL,
-		"%s give up to get IPsec-SA due to time up to wait.\n",
-		saddrwop2str(iph2->dst));
-
-	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
-	if (iph2->side == INITIATOR)
-		pk_sendeacquire(iph2);
-
-	remph2(iph2);
-	delph2(iph2);
-}
 
 /* %%%
  * Quick Mode
@@ -165,8 +131,8 @@
 
 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
 
-	sched_schedule(&iph2->sce, lcconf->wait_ph2complete,
-		       quick_timeover_stub);
+	iph2->sce = sched_new(lcconf->wait_ph2complete,
+		pfkey_timeover_stub, iph2);
 
 	error = 0;
 
@@ -176,7 +142,7 @@
 
 /*
  * send to responder
- * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
+ * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
  */
 int
 quick_i1send(iph2, msg)
@@ -189,14 +155,9 @@
 	char *p;
 	int tlen;
 	int error = ISAKMP_INTERNAL_ERROR;
-	int natoa = ISAKMP_NPTYPE_NONE;
 	int pfsgroup, idci, idcr;
 	int np;
 	struct ipsecdoi_id_b *id, *id_p;
-#ifdef ENABLE_NATT
-	vchar_t *nat_oai = NULL;
-	vchar_t *nat_oar = NULL;
-#endif
 
 	/* validity check */
 	if (msg != NULL) {
@@ -256,49 +217,17 @@
 	 * - no MIP6 or proxy
 	 * - id payload suggests to encrypt all the traffic (no specific
 	 *   protocol type)
-	 * - SA endpoints and IKE addresses for the nego are the same
-	 *   (iph2->src/dst)
 	 */
 	id = (struct ipsecdoi_id_b *)iph2->id->v;
 	id_p = (struct ipsecdoi_id_b *)iph2->id_p->v;
-	if (id->proto_id == 0 &&
-	    id_p->proto_id == 0 &&
-	    iph2->ph1->rmconf->support_proxy == 0 &&
-	    iph2->sa_src == NULL && iph2->sa_dst == NULL &&
-	    ipsecdoi_transportmode(iph2->proposal)) {
+	if (id->proto_id == 0
+	 && id_p->proto_id == 0
+	 && iph2->ph1->rmconf->support_proxy == 0
+	 && ipsecdoi_transportmode(iph2->proposal)) {
 		idci = idcr = 0;
 	} else
 		idci = idcr = 1;
 
-#ifdef ENABLE_NATT
-	/*
-	 * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
-	 * we should send NAT-OA
-	 */
-	if (ipsecdoi_transportmode(iph2->proposal)
-	 && (iph2->ph1->natt_flags & NAT_DETECTED)) {
-		natoa = iph2->ph1->natt_options->payload_nat_oa;
-
-		nat_oai = ipsecdoi_sockaddr2id(iph2->src,
-			IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
-		nat_oar = ipsecdoi_sockaddr2id(iph2->dst,
-			IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
-
-		if (nat_oai == NULL || nat_oar == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"failed to generate NAT-OA payload.\n");
-			goto end;
-		}
-
-		plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAi:\n");
-		plogdump(LLV_DEBUG, nat_oai->v, nat_oai->l);
-		plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAr:\n");
-		plogdump(LLV_DEBUG, nat_oar->v, nat_oar->l);
-	} else {
-		natoa = ISAKMP_NPTYPE_NONE;
-	}
-#endif
-
 	/* create SA;NONCE payload, and KE if need, and IDii, IDir. */
 	tlen = + sizeof(*gen) + iph2->sa->l
 		+ sizeof(*gen) + iph2->nonce->l;
@@ -308,10 +237,6 @@
 		tlen += sizeof(*gen) + iph2->id->l;
 	if (idcr)
 		tlen += sizeof(*gen) + iph2->id_p->l;
-#ifdef ENABLE_NATT
-	if (natoa != ISAKMP_NPTYPE_NONE)
-		tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l;
-#endif
 
 	body = vmalloc(tlen);
 	if (body == NULL) {
@@ -331,30 +256,22 @@
 	else if (idci || idcr)
 		np = ISAKMP_NPTYPE_ID;
 	else
-		np = natoa;
+		np = ISAKMP_NPTYPE_NONE;
 	p = set_isakmp_payload(p, iph2->nonce, np);
 
 	/* add KE payload if need. */
-	np = (idci || idcr) ? ISAKMP_NPTYPE_ID : natoa;
+	np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
 	if (pfsgroup)
 		p = set_isakmp_payload(p, iph2->dhpub, np);
 
 	/* IDci */
-	np = (idcr) ? ISAKMP_NPTYPE_ID : natoa;
+	np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
 	if (idci)
 		p = set_isakmp_payload(p, iph2->id, np);
 
 	/* IDcr */
 	if (idcr)
-		p = set_isakmp_payload(p, iph2->id_p, natoa);
-
-#ifdef ENABLE_NATT
-	/* NAT-OA */
-	if (natoa != ISAKMP_NPTYPE_NONE) {
-		p = set_isakmp_payload(p, nat_oai, natoa);
-		p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE);
-	}
-#endif
+		p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE);
 
 	/* generate HASH(1) */
 	hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
@@ -367,7 +284,8 @@
 		goto end;
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph2send(iph2) == -1)
+	iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
+	if (isakmp_ph2resend(iph2) == -1)
 		goto end;
 
 	/* change status of isakmp status entry */
@@ -380,19 +298,13 @@
 		vfree(body);
 	if (hash != NULL)
 		vfree(hash);
-#ifdef ENABLE_NATT
-	if (nat_oai != NULL)
-		vfree(nat_oai);
-	if (nat_oar != NULL)
-		vfree(nat_oar);
-#endif
 
 	return error;
 }
 
 /*
  * receive from responder
- * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
+ * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
  */
 int
 quick_i2recv(iph2, msg0)
@@ -402,11 +314,10 @@
 	vchar_t *msg = NULL;
 	vchar_t *hbuf = NULL;	/* for hash computing. */
 	vchar_t *pbuf = NULL;	/* for payload parsing */
-	vchar_t *idci = NULL;
-	vchar_t *idcr = NULL;
 	struct isakmp_parse_t *pa;
 	struct isakmp *isakmp = (struct isakmp *)msg0->v;
 	struct isakmp_pl_hash *hash = NULL;
+	int f_id;
 	char *p;
 	int tlen;
 	int error = ISAKMP_INTERNAL_ERROR;
@@ -480,6 +391,7 @@
 	 * copy non-HASH payloads into hbuf, so that we can validate HASH.
 	 */
 	iph2->sa_ret = NULL;
+	f_id = 0;	/* flag to use checking ID */
 	tlen = 0;	/* count payload length except of HASH payload. */
 	for (; pa->type; pa++) {
 
@@ -495,84 +407,54 @@
 					"isn't supported.\n");
 				break;
 			}
-			if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"duplicate ISAKMP_NPTYPE_SA.\n");
+			if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0)
 				goto end;
-			}
 			break;
 
 		case ISAKMP_NPTYPE_NONCE:
-			if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"duplicate ISAKMP_NPTYPE_NONCE.\n");
+			if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
 				goto end;
-			}
 			break;
 
 		case ISAKMP_NPTYPE_KE:
-			if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"duplicate ISAKMP_NPTYPE_KE.\n");
+			if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
 				goto end;
-			}
 			break;
 
 		case ISAKMP_NPTYPE_ID:
-			if (idci == NULL) {
-				if (isakmp_p2ph(&idci, pa->ptr) < 0)
-					goto end;
-			} else if (idcr == NULL) {
-				if (isakmp_p2ph(&idcr, pa->ptr) < 0)
-					goto end;
+		    {
+			vchar_t *vp;
+
+			/* check ID value */
+			if (f_id == 0) {
+				/* for IDci */
+				f_id = 1;
+				vp = iph2->id;
 			} else {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"too many ISAKMP_NPTYPE_ID payloads.\n");
+				/* for IDcr */
+				vp = iph2->id_p;
+			}
+
+#ifndef ANDROID_PATCHED
+			if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) {
+
+				plog(LLV_ERROR, LOCATION, NULL,
+					"mismatched ID was returned.\n");
+				error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
 				goto end;
 			}
+#endif
+		    }
 			break;
 
 		case ISAKMP_NPTYPE_N:
-			ph2_recv_n(iph2, pa->ptr);
+			isakmp_check_notify(pa->ptr, iph2->ph1);
 			break;
 
 #ifdef ENABLE_NATT
 		case ISAKMP_NPTYPE_NATOA_DRAFT:
 		case ISAKMP_NPTYPE_NATOA_RFC:
-		    {
-			struct sockaddr_storage addr;
-			struct sockaddr *daddr;
-			u_int8_t prefix;
-			u_int16_t ul_proto;
-			vchar_t *vp = NULL;
-
-			if (isakmp_p2ph(&vp, pa->ptr) < 0)
-				goto end;
-
-			error = ipsecdoi_id2sockaddr(vp,
-					(struct sockaddr *) &addr,
-					&prefix, &ul_proto);
-
-			vfree(vp);
-
-			if (error)
-				goto end;
-
-			daddr = dupsaddr((struct sockaddr *) &addr);
-			if (daddr == NULL)
-				goto end;
-
-			if (iph2->natoa_src == NULL)
-				iph2->natoa_src = daddr;
-			else if (iph2->natoa_dst == NULL)
-				iph2->natoa_dst = daddr;
-			else {
-				racoon_free(daddr);
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"too many ISAKMP_NPTYPE_NATOA payloads.\n");
-				goto end;
-			}
-		    }
+			/* Ignore original source/destination messages */
 			break;
 #endif
 
@@ -598,105 +480,6 @@
 		goto end;
 	}
 
-#ifndef ANDROID_PATCHED
-	/* identity check */
-	if (idci != NULL) {
-		struct sockaddr_storage proposed_addr, got_addr;
-		u_int8_t proposed_prefix, got_prefix;
-		u_int16_t proposed_ulproto, got_ulproto;
-
-		error = ipsecdoi_id2sockaddr(iph2->id,
-					(struct sockaddr *) &proposed_addr,
-					&proposed_prefix, &proposed_ulproto);
-		if (error)
-			goto end;
-
-		error = ipsecdoi_id2sockaddr(idci,
-					(struct sockaddr *) &got_addr,
-					&got_prefix, &got_ulproto);
-		if (error)
-			goto end;
-
-		if (proposed_prefix != got_prefix
-		 || proposed_ulproto != got_ulproto) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"IDci prefix/ulproto does not match proposal.\n");
-			error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
-			goto end;
-		}
-#ifdef ENABLE_NATT
-		set_port(iph2->natoa_src,
-			 extract_port((struct sockaddr *) &proposed_addr));
-#endif
-
-		if (cmpsaddr((struct sockaddr *) &proposed_addr,
-			     (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"IDci matches proposal.\n");
-#ifdef ENABLE_NATT
-		} else if (iph2->natoa_src != NULL
-			&& cmpsaddr(iph2->natoa_src,
-				    (struct sockaddr *) &got_addr) == 0) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"IDci matches NAT-OAi.\n");
-#endif
-		} else {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"mismatched IDci was returned.\n");
-			error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
-			goto end;
-		}
-	}
-	if (idcr != NULL) {
-		struct sockaddr_storage proposed_addr, got_addr;
-		u_int8_t proposed_prefix, got_prefix;
-		u_int16_t proposed_ulproto, got_ulproto;
-
-		error = ipsecdoi_id2sockaddr(iph2->id_p,
-					(struct sockaddr *) &proposed_addr,
-					&proposed_prefix, &proposed_ulproto);
-		if (error)
-			goto end;
-
-		error = ipsecdoi_id2sockaddr(idcr,
-					(struct sockaddr *) &got_addr,
-					&got_prefix, &got_ulproto);
-		if (error)
-			goto end;
-
-		if (proposed_prefix != got_prefix
-		 || proposed_ulproto != got_ulproto) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"IDcr prefix/ulproto does not match proposal.\n");
-			error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
-			goto end;
-		}
-
-#ifdef ENABLE_NATT
-		set_port(iph2->natoa_dst,
-			 extract_port((struct sockaddr *) &proposed_addr));
-#endif
-
-		if (cmpsaddr((struct sockaddr *) &proposed_addr,
-			     (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"IDcr matches proposal.\n");
-#ifdef ENABLE_NATT
-		} else if (iph2->natoa_dst != NULL
-			&& cmpsaddr(iph2->natoa_dst,
-				    (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"IDcr matches NAT-OAr.\n");
-#endif
-		} else {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"mismatched IDcr was returned.\n");
-			error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
-			goto end;
-		}
-	}
-#endif
-
 	/* Fixed buffer for calculating HASH */
 	memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
 	plog(LLV_DEBUG, LOCATION, NULL,
@@ -733,8 +516,6 @@
 
 	/* validity check SA payload sent from responder */
 	if (ipsecdoi_checkph2proposal(iph2) < 0) {
-		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-			"proposal check failed.\n");
 		error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
 		goto end;
 	}
@@ -751,10 +532,6 @@
 		vfree(pbuf);
 	if (msg)
 		vfree(msg);
-	if (idci)
-		vfree(idci);
-	if (idcr)
-		vfree(idcr);
 
 	if (error) {
 		VPTRINIT(iph2->sa_ret);
@@ -762,16 +539,6 @@
 		VPTRINIT(iph2->dhpub_p);
 		VPTRINIT(iph2->id);
 		VPTRINIT(iph2->id_p);
-#ifdef ENABLE_NATT
-		if (iph2->natoa_src) {
-			racoon_free(iph2->natoa_src);
-			iph2->natoa_src = NULL;
-		}
-		if (iph2->natoa_dst) {
-			racoon_free(iph2->natoa_dst);
-			iph2->natoa_dst = NULL;
-		}
-#endif
 	}
 
 	return error;
@@ -852,7 +619,8 @@
 	/* if there is commit bit, need resending */
 	if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
 		/* send the packet, add to the schedule to resend */
-		if (isakmp_ph2send(iph2) == -1)
+		iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
+		if (isakmp_ph2resend(iph2) == -1)
 			goto end;
 	} else {
 		/* send the packet */
@@ -967,7 +735,7 @@
 				    "Ignoring multiples notifications\n");
 				break;
 			}
-			ph2_recv_n(iph2, pa->ptr);
+			isakmp_check_notify(pa->ptr, iph2->ph1);
 			notify = vmalloc(pa->len);
 			if (notify == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
@@ -1060,7 +828,7 @@
 
 /*
  * receive from initiator
- * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
+ * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
  */
 int
 quick_r1recv(iph2, msg0)
@@ -1094,11 +862,8 @@
 	}
 	/* decrypt packet */
 	msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
-	if (msg == NULL) {
-		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-			"Packet decryption failed.\n");
+	if (msg == NULL)
 		goto end;
-	}
 
 	/* create buffer for using to validate HASH(1) */
 	/*
@@ -1182,27 +947,18 @@
 					"Multi SAs isn't supported.\n");
 				goto end;
 			}
-			if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"duplicate ISAKMP_NPTYPE_SA.\n");
+			if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0)
 				goto end;
-			}
 			break;
 
 		case ISAKMP_NPTYPE_NONCE:
-			if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"duplicate ISAKMP_NPTYPE_NONCE.\n");
+			if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
 				goto end;
-			}
 			break;
 
 		case ISAKMP_NPTYPE_KE:
-			if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"duplicate ISAKMP_NPTYPE_KE.\n");
+			if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
 				goto end;
-			}
 			break;
 
 		case ISAKMP_NPTYPE_ID:
@@ -1235,47 +991,13 @@
 			break;
 
 		case ISAKMP_NPTYPE_N:
-			ph2_recv_n(iph2, pa->ptr);
+			isakmp_check_notify(pa->ptr, iph2->ph1);
 			break;
 
 #ifdef ENABLE_NATT
 		case ISAKMP_NPTYPE_NATOA_DRAFT:
 		case ISAKMP_NPTYPE_NATOA_RFC:
-		    {
-			struct sockaddr_storage addr;
-			struct sockaddr *daddr;
-			u_int8_t prefix;
-			u_int16_t ul_proto;
-			vchar_t *vp = NULL;
-
-			if (isakmp_p2ph(&vp, pa->ptr) < 0)
-				goto end;
-
-			error = ipsecdoi_id2sockaddr(vp,
-					(struct sockaddr *) &addr,
-					&prefix, &ul_proto);
-
-			vfree(vp);
-
-			if (error)
-				goto end;
-
-			daddr = dupsaddr((struct sockaddr *) &addr);
-			if (daddr == NULL)
-				goto end;
-
-			if (iph2->natoa_dst == NULL)
-				iph2->natoa_dst = daddr;
-			else if (iph2->natoa_src == NULL)
-				iph2->natoa_src = daddr;
-			else {
-				racoon_free(daddr);
-				plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-					"received too many NAT-OA payloads.\n");
-				error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
-				goto end;
-			}
-		    }
+			/* Ignore original source/destination messages */
 			break;
 #endif
 
@@ -1358,15 +1080,12 @@
 			plog(LLV_ERROR, LOCATION, NULL,
 				"failed to generate a proposal template "
 				"from client's proposal.\n");
-			error = ISAKMP_INTERNAL_ERROR;
-			goto end;
+			return ISAKMP_INTERNAL_ERROR;
 		}
 		/*FALLTHROUGH*/
 	case 0:
 		/* select single proposal or reject it. */
 		if (ipsecdoi_selectph2proposal(iph2) < 0) {
-			plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-				"no proposal chosen.\n");
 			error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
 			goto end;
 		}
@@ -1416,16 +1135,6 @@
 		VPTRINIT(iph2->dhpub_p);
 		VPTRINIT(iph2->id);
 		VPTRINIT(iph2->id_p);
-#ifdef ENABLE_NATT
-		if (iph2->natoa_src) {
-			racoon_free(iph2->natoa_src);
-			iph2->natoa_src = NULL;
-		}
-		if (iph2->natoa_dst) {
-			racoon_free(iph2->natoa_dst);
-			iph2->natoa_dst = NULL;
-		}
-#endif
 	}
 
 	return error;
@@ -1456,8 +1165,8 @@
 
 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
 
-	sched_schedule(&iph2->sce, lcconf->wait_ph2complete,
-		       quick_timeover_stub);
+	iph2->sce = sched_new(lcconf->wait_ph2complete,
+		pfkey_timeover_stub, iph2);
 
 	error = 0;
 
@@ -1467,7 +1176,7 @@
 
 /*
  * send to initiator
- * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
+ * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
  */
 int
 quick_r2send(iph2, msg)
@@ -1480,13 +1189,8 @@
 	char *p;
 	int tlen;
 	int error = ISAKMP_INTERNAL_ERROR;
-	int natoa = ISAKMP_NPTYPE_NONE;
 	int pfsgroup;
 	u_int8_t *np_p = NULL;
-#ifdef ENABLE_NATT
-	vchar_t *nat_oai = NULL;
-	vchar_t *nat_oar = NULL;
-#endif
 
 	/* validity check */
 	if (msg != NULL) {
@@ -1527,33 +1231,6 @@
 		}
 	}
 
-#ifdef ENABLE_NATT
-	/*
-	 * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
-	 * we should send NAT-OA
-	 */
-	if (ipsecdoi_transportmode(iph2->proposal)
-	 && (iph2->ph1->natt_flags & NAT_DETECTED)) {
-		natoa = iph2->ph1->natt_options->payload_nat_oa;
-
-		nat_oai = ipsecdoi_sockaddr2id(iph2->dst,
-			IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
-		nat_oar = ipsecdoi_sockaddr2id(iph2->src,
-			IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
-
-		if (nat_oai == NULL || nat_oar == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"failed to generate NAT-OA payload.\n");
-			goto end;
-		}
-
-		plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAi:\n");
-		plogdump(LLV_DEBUG, nat_oai->v, nat_oai->l);
-		plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAr:\n");
-		plogdump(LLV_DEBUG, nat_oar->v, nat_oar->l);
-	}
-#endif
-
 	/* create SA;NONCE payload, and KE and ID if need */
 	tlen = sizeof(*gen) + iph2->sa_ret->l
 		+ sizeof(*gen) + iph2->nonce->l;
@@ -1562,10 +1239,6 @@
 	if (iph2->id_p != NULL)
 		tlen += (sizeof(*gen) + iph2->id_p->l
 			+ sizeof(*gen) + iph2->id->l);
-#ifdef ENABLE_NATT
-	if (natoa != ISAKMP_NPTYPE_NONE)
-		tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l;
-#endif
 
 	body = vmalloc(tlen);
 	if (body == NULL) { 
@@ -1585,14 +1258,14 @@
 				? ISAKMP_NPTYPE_KE
 				: (iph2->id_p != NULL
 					? ISAKMP_NPTYPE_ID
-					: natoa));
+					: ISAKMP_NPTYPE_NONE));
 
 	/* add KE payload if need. */
 	if (iph2->dhpub_p != NULL && pfsgroup != 0) {
 		np_p = &((struct isakmp_gen *)p)->np;	/* XXX */
 		p = set_isakmp_payload(p, iph2->dhpub,
 			(iph2->id_p == NULL)
-				? natoa
+				? ISAKMP_NPTYPE_NONE
 				: ISAKMP_NPTYPE_ID);
 	}
 
@@ -1602,17 +1275,9 @@
 		p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
 		/* IDcr */
 		np_p = &((struct isakmp_gen *)p)->np;	/* XXX */
-		p = set_isakmp_payload(p, iph2->id, natoa);
+		p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE);
 	}
 
-#ifdef ENABLE_NATT
-	/* NAT-OA */
-	if (natoa != ISAKMP_NPTYPE_NONE) {
-		p = set_isakmp_payload(p, nat_oai, natoa);
-		p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE);
-	}
-#endif
-
 	/* add a RESPONDER-LIFETIME notify payload if needed */
     {
 	vchar_t *data = NULL;
@@ -1685,7 +1350,8 @@
 		goto end;
 
 	/* send the packet, add to the schedule to resend */
-	if (isakmp_ph2send(iph2) == -1)
+	iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
+	if (isakmp_ph2resend(iph2) == -1)
 		goto end;
 
 	/* the sending message is added to the received-list. */
@@ -1705,12 +1371,6 @@
 		vfree(body);
 	if (hash != NULL)
 		vfree(hash);
-#ifdef ENABLE_NATT
-	if (nat_oai != NULL)
-		vfree(nat_oai);
-	if (nat_oar != NULL)
-		vfree(nat_oar);
-#endif
 
 	return error;
 }
@@ -1718,7 +1378,6 @@
 /*
  * receive from initiator
  * 	HDR*, HASH(3)
-
  */
 int
 quick_r3recv(iph2, msg0)
@@ -1762,7 +1421,7 @@
 			hash = (struct isakmp_pl_hash *)pa->ptr;
 			break;
 		case ISAKMP_NPTYPE_N:
-			ph2_recv_n(iph2, pa->ptr);
+			isakmp_check_notify(pa->ptr, iph2->ph1);
 			break;
 		default:
 			/* don't send information, see ident_r1recv() */
@@ -2143,11 +1802,25 @@
 get_sainfo_r(iph2)
 	struct ph2handle *iph2;
 {
-	vchar_t *idsrc = NULL, *iddst = NULL, *client = NULL;
+	vchar_t *idsrc = NULL, *iddst = NULL;
+	int prefixlen;
 	int error = ISAKMP_INTERNAL_ERROR;
+	int remoteid = 0;
 
 	if (iph2->id == NULL) {
-		idsrc = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST,
+		switch (iph2->src->sa_family) {
+		case AF_INET:
+			prefixlen = sizeof(struct in_addr) << 3;
+			break;
+		case AF_INET6:
+			prefixlen = sizeof(struct in6_addr) << 3;
+			break;
+		default:
+			plog(LLV_ERROR, LOCATION, NULL,
+				"invalid family: %d\n", iph2->src->sa_family);
+			goto end;
+		}
+		idsrc = ipsecdoi_sockaddr2id(iph2->src, prefixlen,
 					IPSEC_ULPROTO_ANY);
 	} else {
 		idsrc = vdup(iph2->id);
@@ -2159,7 +1832,19 @@
 	}
 
 	if (iph2->id_p == NULL) {
-		iddst = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST,
+		switch (iph2->dst->sa_family) {
+		case AF_INET:
+			prefixlen = sizeof(struct in_addr) << 3;
+			break;
+		case AF_INET6:
+			prefixlen = sizeof(struct in6_addr) << 3;
+			break;
+		default:
+			plog(LLV_ERROR, LOCATION, NULL,
+				"invalid family: %d\n", iph2->dst->sa_family);
+			goto end;
+		}
+		iddst = ipsecdoi_sockaddr2id(iph2->dst, prefixlen,
 					IPSEC_ULPROTO_ANY);
 	} else {
 		iddst = vdup(iph2->id_p);
@@ -2170,34 +1855,19 @@
 		goto end;
 	}
 
-#ifdef ENABLE_HYBRID
-
-	/* clientaddr check : obtain modecfg address */
-	if (iph2->ph1->mode_cfg != NULL) {
-		if ((iph2->ph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
-		    (iph2->ph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)){
-			struct sockaddr saddr;
-			saddr.sa_family = AF_INET;
-#ifndef __linux__
-			saddr.sa_len = sizeof(struct sockaddr_in);
-#endif
-			((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY;
-			memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, 
-				&iph2->ph1->mode_cfg->addr4, sizeof(struct in_addr));
-			client = ipsecdoi_sockaddr2id(&saddr, 32, IPSEC_ULPROTO_ANY);
-		}
-	}
-
-	/* clientaddr check, fallback to peer address */
-	if (client == NULL)
 	{
-		client = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST,
-					IPSEC_ULPROTO_ANY);
+		struct remoteconf *conf;
+		conf = getrmconf(iph2->dst);
+		if (conf != NULL)
+			remoteid=conf->ph1id;
+		else{
+			plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n");
+			remoteid=0;
+		}
+		
 	}
-#endif
 
-	/* obtain a matching sainfo section */
-	iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, client, iph2->ph1->rmconf->ph1id);
+	iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, remoteid);
 	if (iph2->sainfo == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to get sainfo.\n");
@@ -2220,8 +1890,6 @@
 		vfree(idsrc);
 	if (iddst)
 		vfree(iddst);
-	if (client)
-		vfree(client);
 
 	return error;
 }
@@ -2253,8 +1921,8 @@
 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
 	}
 
-	/* make sure if sa_[src, dst] are null. */
-	if (iph2->sa_src || iph2->sa_dst) {
+	/* make sure if id[src,dst] is null. */
+	if (iph2->src_id || iph2->dst_id) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"Why do ID[src,dst] exist already.\n");
 		return ISAKMP_INTERNAL_ERROR;
@@ -2358,45 +2026,29 @@
 		}
 #endif
 
-		/* Before setting iph2->[sa_src, sa_dst] with the addresses
-		 * provided in ID payloads, we check:
-		 * - they are both addresses of same family
-		 * - sainfo has not been selected only based on ID payload
-		 *   information but also based on specific Phase 1
-		 *   credentials (iph2->sainfo->id_i is defined), i.e.
-		 *   local configuration _explicitly_ expect that user
-		 *   (e.g. from asn1dn "C=FR, ...") with those IDs) */
-		if (_XIDT(iph2->id_p) == idi2type &&
-		    spidx.dst.ss_family == spidx.src.ss_family &&
-		    iph2->sainfo && iph2->sainfo->id_i) {
-
-			iph2->sa_src = dupsaddr((struct sockaddr *)&spidx.dst);
-			if (iph2->sa_src  == NULL) {
+		/* make id[src,dst] if both ID types are IP address and same */
+		if (_XIDT(iph2->id_p) == idi2type
+		 && spidx.dst.ss_family == spidx.src.ss_family) {
+			iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst);
+			if (iph2->src_id  == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
 				    "buffer allocation failed.\n");
 				return ISAKMP_INTERNAL_ERROR;
 			}
-
-			iph2->sa_dst = dupsaddr((struct sockaddr *)&spidx.src);
-			if (iph2->sa_dst  == NULL) {
+			iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src);
+			if (iph2->dst_id  == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
 				    "buffer allocation failed.\n");
 				return ISAKMP_INTERNAL_ERROR;
 			}
-		} else {
-			plog(LLV_DEBUG, LOCATION, NULL,
-			     "Either family (%d - %d), types (%d - %d) of ID "
-			     "from initiator differ or matching sainfo "
-			     "has no id_i defined for the peer. Not filling "
-			     "iph2->sa_src and iph2->sa_dst.\n",
-			     spidx.src.ss_family, spidx.dst.ss_family,
-			     _XIDT(iph2->id_p),idi2type);
 		}
+
 	} else {
 		plog(LLV_DEBUG, LOCATION, NULL,
-		     "get a source address of SP index from Phase 1"
-		     "addresses due to no ID payloads found"
-		     "OR because ID type is not address.\n");
+			"get a source address of SP index "
+			"from phase1 address "
+			"due to no ID payloads found "
+			"OR because ID type is not address.\n");
 
 		/* see above comment. */
 		memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
@@ -2418,7 +2070,7 @@
 #undef _XIDT
 
 	plog(LLV_DEBUG, LOCATION, NULL,
-		"get src address from ID payload "
+		"get a src address from ID payload "
 		"%s prefixlen=%u ul_proto=%u\n",
 		saddr2str((struct sockaddr *)&spidx.src),
 		spidx.prefs, spidx.ul_proto);
@@ -2532,76 +2184,6 @@
 	}
 #endif /* HAVE_SECCTX */
 
-	iph2->spid = sp_in->id;
-
-	return 0;
-}
-
-/*
- * handle a notification payload inside phase2 exchange.
- * phase2 is always encrypted, so it does not need to be checked
- * for explicitely.
- */
-static int
-ph2_recv_n(iph2, gen)
-	struct ph2handle *iph2;
-	struct isakmp_gen *gen;
-{
-	struct ph1handle *iph1 = iph2->ph1;
-	struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen;
-	u_int type;
-	int check_level;
-
-	type = ntohs(notify->type);
-	switch (type) {
-	case ISAKMP_NTYPE_CONNECTED:
-		break;
-	case ISAKMP_NTYPE_INITIAL_CONTACT:
-		return isakmp_info_recv_initialcontact(iph1, iph2);
-	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
-		ipsecdoi_parse_responder_lifetime(notify,
-			&iph2->lifetime_secs, &iph2->lifetime_kb);
-
-		if (iph1 != NULL && iph1->rmconf != NULL) {
-			check_level = iph1->rmconf->pcheck_level;
-		} else {
-			if (iph1 != NULL)
-				plog(LLV_DEBUG, LOCATION, NULL,
-					"No phase1 rmconf found !\n");
-			else
-				plog(LLV_DEBUG, LOCATION, NULL,
-					"No phase1 found !\n");
-			check_level = PROP_CHECK_EXACT;
-		}
-
-		switch (check_level) {
-		case PROP_CHECK_OBEY:
-			break;
-		case PROP_CHECK_STRICT:
-		case PROP_CHECK_CLAIM:
-			if (iph2->sainfo == NULL
-			 || iph2->sainfo->lifetime <= iph2->lifetime_secs) {
-				plog(LLV_WARNING, LOCATION, NULL,
-					"RESPONDER-LIFETIME: lifetime mismatch\n");
-				iph2->lifetime_secs = 0;
-			}
-			break;
-		case PROP_CHECK_EXACT:
-			if (iph2->sainfo == NULL
-			 || iph2->sainfo->lifetime != iph2->lifetime_secs) {
-				plog(LLV_WARNING, LOCATION, NULL,
-					"RESPONDER-LIFETIME: lifetime mismatch\n");
-				iph2->lifetime_secs = 0;
-			}
-			break;
-		}
-		break;
-	default:
-		isakmp_log_notify(iph2->ph1, notify, "phase2 exchange");
-		isakmp_info_send_n2(iph2, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE,
-			NULL);
-		break;
-	}
 	return 0;
 }
 
diff --git a/src/racoon/isakmp_unity.c b/src/racoon/isakmp_unity.c
index a1bf793..9873f59 100644
--- a/src/racoon/isakmp_unity.c
+++ b/src/racoon/isakmp_unity.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_unity.c,v 1.9 2007/10/19 03:37:19 manu Exp $	*/
+/*	$NetBSD: isakmp_unity.c,v 1.7 2006/10/09 06:17:20 manu Exp $	*/
 
 /* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */
 
@@ -305,41 +305,32 @@
 	struct unity_network * network;
 	int *count;
 {
-	struct unity_netentry * nentry;
-
-	/*
-	 * search for network in current list
-	 * to avoid adding duplicates
-	 */
-	for (nentry = *list; nentry != NULL; nentry = nentry->next)
-		if (memcmp(&nentry->network, network,
-			   sizeof(struct unity_network)) == 0)
-			return 0;	/* it's a dupe */
+	struct unity_netentry * newentry;
 
 	/*
 	 * allocate new netentry and copy
-	 * new splitnet network data
+         * new splitnet network data
 	 */
-	nentry = (struct unity_netentry *)
+	newentry = (struct unity_netentry *)
 		racoon_malloc(sizeof(struct unity_netentry));
-	if (nentry == NULL)
+	if (newentry == NULL)
 		return -1;
 
-	memcpy(&nentry->network,network,
+	memcpy(&newentry->network,network,
 		sizeof(struct unity_network));
-	nentry->next = NULL;
+	newentry->next = NULL;
 
 	/*
 	 * locate the last netentry in our
 	 * splitnet list and add our entry
 	 */
 	if (*list == NULL)
-		*list = nentry;
+		*list = newentry;
 	else {
 		struct unity_netentry * tmpentry = *list;
 		while (tmpentry->next != NULL)
 			tmpentry = tmpentry->next;
-		tmpentry->next = nentry;
+		tmpentry->next = newentry;
 	}
 
 	(*count)++;
@@ -363,9 +354,8 @@
 	}
 }
 
-char * splitnet_list_2str(list, splitnet_ipaddr)
+char * splitnet_list_2str(list)
 	struct unity_netentry * list;
-	enum splinet_ipaddr splitnet_ipaddr;
 {
 	struct unity_netentry * netentry;
 	char tmp1[40];
@@ -399,17 +389,8 @@
 
 		inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
 		inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
-		if (splitnet_ipaddr == CIDR) {
-			uint32_t tmp3;
-			int cidrmask;
 
-			tmp3 = ntohl(netentry->network.mask4.s_addr);
-			for (cidrmask = 0; tmp3 != 0; cidrmask++)
-				tmp3 <<= 1;
-			len += sprintf(str+len, "%s/%d ", tmp1, cidrmask);
-		} else {
-			len += sprintf(str+len, "%s/%s ", tmp1, tmp2);
-		}
+		len += sprintf(str+len, "%s/%s ", tmp1, tmp2);
 
 		netentry = netentry->next;
 	}
diff --git a/src/racoon/isakmp_unity.h b/src/racoon/isakmp_unity.h
index 3667d0d..b52f02c 100644
--- a/src/racoon/isakmp_unity.h
+++ b/src/racoon/isakmp_unity.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_unity.h,v 1.5 2007/10/19 03:37:19 manu Exp $	*/
+/*	$NetBSD: isakmp_unity.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /*	$KAME$ */
 
@@ -31,8 +31,6 @@
  * SUCH DAMAGE.
  */
 
-enum splinet_ipaddr { NETMASK, CIDR }; 
-
 /* ISAKMP notifies specific to the Unity vendor Id */
 /* Sent during xauth if the user types his password too slowly */
 #define ISAKMP_NTYPE_UNITY_HEARTBEAT	40500
@@ -68,7 +66,7 @@
 
 int	splitnet_list_add(struct unity_netentry **, struct unity_network *, int *);
 void	splitnet_list_free(struct unity_netentry *, int *);
-char *	splitnet_list_2str(struct unity_netentry *, enum splinet_ipaddr);
+char *	splitnet_list_2str(struct unity_netentry *);
 
 vchar_t *isakmp_unity_req(struct ph1handle *, struct isakmp_data *);
 void isakmp_unity_reply(struct ph1handle *, struct isakmp_data *);
diff --git a/src/racoon/isakmp_var.h b/src/racoon/isakmp_var.h
index 09e4e7f..f4ef45d 100644
--- a/src/racoon/isakmp_var.h
+++ b/src/racoon/isakmp_var.h
@@ -1,11 +1,11 @@
-/*	$NetBSD: isakmp_var.h,v 1.17 2010/11/12 10:36:37 tteras Exp $	*/
+/*	$NetBSD: isakmp_var.h,v 1.6.6.1 2007/02/20 09:08:49 vanhu Exp $	*/
 
 /* Id: isakmp_var.h,v 1.12 2005/05/07 14:45:31 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -35,7 +35,6 @@
 #define _ISAKMP_VAR_H
 
 #include "vmbuf.h"
-#include "policy.h"
 
 #define PORT_ISAKMP 500
 #define PORT_ISAKMP_NATT 4500
@@ -57,39 +56,40 @@
 struct ph1handle;
 struct ph2handle;
 struct remoteconf;
+struct isakmp_gen;
 struct ipsecdoi_pl_id;	/* XXX */
 struct isakmp_pl_ke;	/* XXX */
 struct isakmp_pl_nonce;	/* XXX */
 
-extern struct ph1handle *isakmp_ph1begin_i __P((struct remoteconf *,
-	struct sockaddr *, struct sockaddr *));
+extern int isakmp_handler __P((int));
+extern int isakmp_ph1begin_i __P((struct remoteconf *, struct sockaddr *,
+	struct sockaddr *));
 
 extern vchar_t *isakmp_parsewoh __P((int, struct isakmp_gen *, int));
 extern vchar_t *isakmp_parse __P((vchar_t *));
 
 extern int isakmp_init __P((void));
 extern const char *isakmp_pindex __P((const isakmp_index *, const u_int32_t));
-extern int isakmp_open __P((struct sockaddr *, int));
-extern void isakmp_close __P((int fd));
+extern int isakmp_open __P((void));
+extern void isakmp_close __P((void));
 extern int isakmp_send __P((struct ph1handle *, vchar_t *));
 
-extern int isakmp_ph1send __P((struct ph1handle *));
-extern int isakmp_ph2send __P((struct ph2handle *));
-extern void isakmp_ph1dying_stub __P((struct sched *));
-extern void isakmp_ph1dying __P((struct ph1handle *));
-extern void isakmp_ph1expire_stub __P((struct sched *));
+extern void isakmp_ph1resend_stub __P((void *));
+extern int isakmp_ph1resend __P((struct ph1handle *));
+extern void isakmp_ph2resend_stub __P((void *));
+extern int isakmp_ph2resend __P((struct ph2handle *));
+extern void isakmp_ph1expire_stub __P((void *));
 extern void isakmp_ph1expire __P((struct ph1handle *));
-extern void isakmp_ph1delete_stub __P((struct sched *));
+extern void isakmp_ph1delete_stub __P((void *));
 extern void isakmp_ph1delete __P((struct ph1handle *));
-extern void isakmp_ph2expire_stub __P((struct sched *));
+extern void isakmp_ph2expire_stub __P((void *));
 extern void isakmp_ph2expire __P((struct ph2handle *));
-extern void isakmp_ph2delete_stub __P((struct sched *));
+extern void isakmp_ph2delete_stub __P((void *));
 extern void isakmp_ph2delete __P((struct ph2handle *));
 
-extern int isakmp_get_sainfo __P((struct ph2handle *, struct secpolicy *, struct secpolicy *));
-extern int isakmp_post_acquire __P((struct ph2handle *, struct ph1handle *, int));
+extern int isakmp_post_acquire __P((struct ph2handle *));
 extern int isakmp_post_getspi __P((struct ph2handle *));
-extern void isakmp_chkph1there_stub __P((struct sched *));
+extern void isakmp_chkph1there_stub __P((void *));
 extern void isakmp_chkph1there __P((struct ph2handle *));
 
 extern caddr_t isakmp_set_attr_v __P((caddr_t, int, caddr_t, int));
@@ -106,19 +106,8 @@
 extern caddr_t set_isakmp_header2 __P((vchar_t *, struct ph2handle *, int));
 extern caddr_t set_isakmp_payload __P((caddr_t, vchar_t *, int));
 
-extern struct payload_list *isakmp_plist_append_full __P((
-	struct payload_list *plist, vchar_t *payload,
-	u_int8_t payload_type, u_int8_t free));
-
-static inline struct payload_list *isakmp_plist_append(plist, payload, payload_type)
-	struct payload_list *plist;
-	vchar_t *payload;
-	u_int8_t payload_type;
-{
-	return isakmp_plist_append_full(plist, payload, payload_type, 0);
-}
-
-
+extern struct payload_list *isakmp_plist_append __P((struct payload_list *plist, 
+	vchar_t *payload, int payload_type));
 extern vchar_t *isakmp_plist_set_all __P((struct payload_list **plist,
 	struct ph1handle *iph1));
 
@@ -131,7 +120,7 @@
 	struct remoteconf *, struct sockaddr *, struct sockaddr *));
 extern void log_ph1established __P((const struct ph1handle *));
 
-extern void script_hook __P((struct ph1handle *, int));
+extern void script_hook __P((struct ph1handle *, int)); 
 extern int script_env_append __P((char ***, int *, char *, char *));
 extern int script_exec __P((char *, int, char * const *));
 
@@ -140,5 +129,4 @@
 #ifdef INET6
 u_int32_t setscopeid __P((struct sockaddr *, struct sockaddr *));
 #endif
-
 #endif /* _ISAKMP_VAR_H */
diff --git a/src/racoon/isakmp_xauth.c b/src/racoon/isakmp_xauth.c
index 5d86c68..a0b799d 100644
--- a/src/racoon/isakmp_xauth.c
+++ b/src/racoon/isakmp_xauth.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_xauth.c,v 1.22 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: isakmp_xauth.c,v 1.11.6.2 2009/04/20 13:35:36 tteras Exp $	*/
 
 /* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
 
@@ -40,7 +40,6 @@
 
 #include <netinet/in.h>
 
-#include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -96,9 +95,9 @@
 
 #ifdef HAVE_LIBRADIUS
 #include <radlib.h>
+
 struct rad_handle *radius_auth_state = NULL;
 struct rad_handle *radius_acct_state = NULL;
-struct xauth_rad_config xauth_rad_config;
 #endif
 
 #ifdef HAVE_LIBPAM
@@ -130,7 +129,7 @@
 	size_t tlen;
 
 	/* Status checks */
-	if (iph1->status < PHASE1ST_ESTABLISHED) {
+	if (iph1->status != PHASE1ST_ESTABLISHED) {
 		plog(LLV_ERROR, LOCATION, NULL, 
 		    "Xauth request while phase 1 is not completed\n");
 		return;
@@ -312,7 +311,7 @@
 		 * On failure, throttle the connexion for the remote host
 		 * in order to make password attacks more difficult.
 		 */
-		throttle_delay = throttle_host(iph1->remote, res);
+		throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
 		if (throttle_delay > 0) {
 			char *str;
 
@@ -330,7 +329,7 @@
 		if (throttle_delay != 0) {
 			struct xauth_reply_arg *xra;
 
-			if ((xra = racoon_calloc(1, sizeof(*xra))) == NULL) {
+			if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL, 
 				    "malloc failed, bypass throttling\n");
 				return xauth_reply(iph1, port, id, res);
@@ -345,8 +344,7 @@
 			xra->port = port;
 			xra->id = id;
 			xra->res = res;
-			sched_schedule(&xra->sc, throttle_delay,
-				       xauth_reply_stub);
+			sched_new(throttle_delay, xauth_reply_stub, xra);
 		} else {
 			return xauth_reply(iph1, port, id, res);
 		}
@@ -356,10 +354,10 @@
 }
 
 void 
-xauth_reply_stub(sc)
-	struct sched *sc;
+xauth_reply_stub(args)
+	void *args;
 {
-	struct xauth_reply_arg *xra = container_of(sc, struct xauth_reply_arg, sc);
+	struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
 	struct ph1handle *iph1;
 
 	if ((iph1 = getph1byindex(&xra->index)) != NULL)
@@ -369,6 +367,7 @@
 		    "Delayed Xauth reply: phase 1 no longer exists.\n"); 
 
 	racoon_free(xra);
+	return;
 }
 
 int
@@ -391,7 +390,7 @@
 		xst->status = XAUTHST_NOTYET;
 
 		/* Delete Phase 1 SA */
-		if (iph1->status >= PHASE1ST_ESTABLISHED)
+		if (iph1->status == PHASE1ST_ESTABLISHED)
 			isakmp_info_send_d1(iph1);
 		remph1(iph1);
 		delph1(iph1);
@@ -448,31 +447,6 @@
 
 #ifdef HAVE_LIBRADIUS
 int
-xauth_radius_init_conf(int free)
-{
-	/* free radius config resources */
-	if (free) {
-		int i;
-		for (i = 0; i < xauth_rad_config.auth_server_count; i++) {
-			vfree(xauth_rad_config.auth_server_list[i].host);
-			vfree(xauth_rad_config.auth_server_list[i].secret);
-		}
-		for (i = 0; i < xauth_rad_config.acct_server_count; i++) {
-			vfree(xauth_rad_config.acct_server_list[i].host);
-			vfree(xauth_rad_config.acct_server_list[i].secret);
-		}
-		if (radius_auth_state != NULL)
-			rad_close(radius_auth_state);
-		if (radius_acct_state != NULL)
-			rad_close(radius_acct_state);
-	}
-
-	/* initialize radius config */
-	memset(&xauth_rad_config, 0, sizeof(xauth_rad_config));
-	return 0;
-}
-
-int
 xauth_radius_init(void)
 {
 	/* For first time use, initialize Radius */
@@ -484,35 +458,13 @@
 			return -1;
 		}
 
-		int auth_count = xauth_rad_config.auth_server_count;
-		int auth_added = 0;
-		if (auth_count) {
-			int i;
-			for (i = 0; i < auth_count; i++) {
-				if(!rad_add_server(
-					radius_auth_state,
-					xauth_rad_config.auth_server_list[i].host->v,
-					xauth_rad_config.auth_server_list[i].port,
-					xauth_rad_config.auth_server_list[i].secret->v,
-					xauth_rad_config.timeout,
-					xauth_rad_config.retries ))
-					auth_added++;
-				else
-					plog(LLV_WARNING, LOCATION, NULL,
-						"could not add radius auth server %s\n",
-						xauth_rad_config.auth_server_list[i].host->v);
-			}
-		}
-
-		if (!auth_added) {
-			if (rad_config(radius_auth_state, NULL) != 0) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "Cannot open libradius config file: %s\n", 
-				    rad_strerror(radius_auth_state));
-				rad_close(radius_auth_state);
-				radius_auth_state = NULL;
-				return -1;
-			}
+		if (rad_config(radius_auth_state, NULL) != 0) {
+			plog(LLV_ERROR, LOCATION, NULL, 
+			    "Cannot open librarius config file: %s\n", 
+			    rad_strerror(radius_auth_state));
+			rad_close(radius_auth_state);
+			radius_auth_state = NULL;
+			return -1;
 		}
 	}
 
@@ -524,35 +476,13 @@
 			return -1;
 		}
 
-		int acct_count = xauth_rad_config.acct_server_count;
-		int acct_added = 0;
-		if (acct_count) {
-			int i;
-			for (i = 0; i < acct_count; i++) {
-				if(!rad_add_server(
-					radius_acct_state,
-					xauth_rad_config.acct_server_list[i].host->v,
-					xauth_rad_config.acct_server_list[i].port,
-					xauth_rad_config.acct_server_list[i].secret->v,
-					xauth_rad_config.timeout,
-					xauth_rad_config.retries ))
-					acct_added++;
-				else
-					plog(LLV_WARNING, LOCATION, NULL,
-						"could not add radius account server %s\n",
-						xauth_rad_config.acct_server_list[i].host->v);
-			}
-		}
-
-		if (!acct_added) {
-			if (rad_config(radius_acct_state, NULL) != 0) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "Cannot open libradius config file: %s\n", 
-				    rad_strerror(radius_acct_state));
-				rad_close(radius_acct_state);
-				radius_acct_state = NULL;
-				return -1;
-			}
+		if (rad_config(radius_acct_state, NULL) != 0) {
+			plog(LLV_ERROR, LOCATION, NULL, 
+			    "Cannot open librarius config file: %s\n", 
+			    rad_strerror(radius_acct_state));
+			rad_close(radius_acct_state);
+			radius_acct_state = NULL;
+			return -1;
 		}
 	}
 
@@ -740,7 +670,7 @@
 		    "cannot allocate memory: %s\n", strerror(errno)); 
 		goto out;
 	}
-
+	
 	if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
 		plog(LLV_ERROR, LOCATION, NULL, 
 		    "pam_set_item failed: %s\n", 
@@ -748,13 +678,6 @@
 		goto out;
 	}
 
-	if ((error = pam_set_item(pam, PAM_RUSER, usr)) != 0) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "pam_set_item failed: %s\n", 
-		    pam_strerror(pam, error));
-		goto out;
-	}
-
 	PAM_usr = usr;
 	PAM_pwd = pwd;
 	error = pam_authenticate(pam, 0);
@@ -797,7 +720,7 @@
 
 #ifdef HAVE_LIBLDAP
 int 
-xauth_ldap_init_conf(void)
+xauth_ldap_init(void)
 {
 	int tmplen;
 	int error = -1;
@@ -1336,7 +1259,7 @@
 	 * status. It does it if the chose authmethod is using Xauth.
 	 * On the client side (roadwarrior), we don't check anything.
 	 */
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
@@ -1500,8 +1423,8 @@
 		break;
 
 #ifdef ANDROID_PATCHED
-	case XAUTH_PASSCODE:
-#endif
+        case XAUTH_PASSCODE:
+#endif  
 	case XAUTH_USER_PASSWORD:
 		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
 			return NULL;
@@ -1589,8 +1512,8 @@
 		memcpy(data, iph1->rmconf->xauth->login->v, dlen);
 		break;
 #ifdef ANDROID_PATCHED
-	case XAUTH_PASSCODE:
-#endif
+        case XAUTH_PASSCODE:
+#endif  
 	case XAUTH_USER_PASSWORD:
 		memcpy(data, pwd->v, dlen);
 		break;
@@ -1633,9 +1556,9 @@
 		 * when running as a client (initiator).
 		 */
 		xst = &iph1->mode_cfg->xauth;
-		switch (iph1->approval->authmethod) {
+		switch(AUTHMETHOD(iph1)) {
 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
-		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+		case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
 		/* Not implemented ... */
 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
@@ -1655,11 +1578,13 @@
 			plog(LLV_ERROR, LOCATION, NULL, 
 			    "Xauth authentication failed\n");
 
-			evt_phase1(iph1, EVT_PHASE1_XAUTH_FAILED, NULL);
+			EVT_PUSH(iph1->local, iph1->remote, 
+			    EVTT_XAUTH_FAILED, NULL);
 
 			iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
 		} else {
-			evt_phase1(iph1, EVT_PHASE1_XAUTH_SUCCESS, NULL);
+			EVT_PUSH(iph1->local, iph1->remote, 
+			    EVTT_XAUTH_SUCCESS, NULL);
 		}
 
 
@@ -1774,42 +1699,3 @@
 
 	return;
 }
-
-struct xauth_rmconf *
-xauth_rmconf_dup(xauth_rmconf)
-	struct xauth_rmconf *xauth_rmconf;
-{
-	struct xauth_rmconf *new;
-
-	if (xauth_rmconf != NULL) {
-		new = racoon_malloc(sizeof(*new));
-		if (new == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL, 
-			    "xauth_rmconf_dup: malloc failed\n");
-			return NULL;
-		}
-
-		memcpy(new, xauth_rmconf, sizeof(*new));
-
-		if (xauth_rmconf->login != NULL) {
-			new->login = vdup(xauth_rmconf->login);
-			if (new->login == NULL) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "xauth_rmconf_dup: malloc failed (login)\n");
-				return NULL;
-			}
-		}
-		if (xauth_rmconf->pass != NULL) {
-			new->pass = vdup(xauth_rmconf->pass);
-			if (new->pass == NULL) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "xauth_rmconf_dup: malloc failed (password)\n");
-				return NULL;
-			}
-		}
-
-		return new;
-	}
-
-	return NULL;
-}
diff --git a/src/racoon/isakmp_xauth.h b/src/racoon/isakmp_xauth.h
index f9e778f..ebb5214 100644
--- a/src/racoon/isakmp_xauth.h
+++ b/src/racoon/isakmp_xauth.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_xauth.h,v 1.7 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: isakmp_xauth.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /*	$KAME$ */
 
@@ -34,8 +34,6 @@
 #ifndef _ISAKMP_XAUTH_H
 #define _ISAKMP_XAUTH_H
 
-#include "schedule.h"
-
 /* ISAKMP mode config attribute types specific to the Xauth vendor ID */
 #define	XAUTH_TYPE                16520
 #define	XAUTH_USER_NAME           16521
@@ -92,7 +90,6 @@
 #define XAUTHST_OK	2
 
 struct xauth_reply_arg {
-	struct sched sc;
 	isakmp_index index;
 	int port;
 	int id;
@@ -110,43 +107,20 @@
 vchar_t *isakmp_xauth_req(struct ph1handle *, struct isakmp_data *);
 vchar_t *isakmp_xauth_set(struct ph1handle *, struct isakmp_data *);
 void xauth_rmstate(struct xauth_state *);
-void xauth_reply_stub(struct sched *);
+void xauth_reply_stub(void *);
 int xauth_reply(struct ph1handle *, int, int, int);
 int xauth_rmconf_used(struct xauth_rmconf **);
 void xauth_rmconf_delete(struct xauth_rmconf **);
-struct xauth_rmconf * xauth_rmconf_dup(struct xauth_rmconf *);
+
+#ifdef HAVE_LIBRADIUS
+int xauth_login_radius(struct ph1handle *, char *, char *);
+int xauth_radius_init(void);
+#endif
 
 #ifdef HAVE_LIBPAM
 int xauth_login_pam(int, struct sockaddr *, char *, char *);
 #endif
 
-#ifdef HAVE_LIBRADIUS
-
-#define RADIUS_MAX_SERVERS 5
-
-struct rad_serv {
-	vchar_t		*host;
-	int		port;
-	vchar_t		*secret;
-};
-
-struct xauth_rad_config {
-	struct rad_serv	auth_server_list[RADIUS_MAX_SERVERS];
-	int		auth_server_count;
-	struct rad_serv	acct_server_list[RADIUS_MAX_SERVERS];
-	int		acct_server_count;
-	int		timeout;
-	int		retries;
-};
-
-extern struct xauth_rad_config xauth_rad_config;
-
-int xauth_radius_init_conf(int free);
-int xauth_radius_init(void);
-int xauth_login_radius(struct ph1handle *, char *, char *);
-
-#endif
-
 #ifdef HAVE_LIBLDAP
 
 #define LDAP_DFLT_HOST		"localhost"
@@ -174,9 +148,8 @@
 
 extern struct xauth_ldap_config xauth_ldap_config;
 
-int xauth_ldap_init_conf(void);
+int xauth_ldap_init(void);
 int xauth_login_ldap(struct ph1handle *, char *, char *);
-
 #endif
 
 #endif /* _ISAKMP_XAUTH_H */
diff --git a/src/racoon/kmpstat.c b/src/racoon/kmpstat.c
index 50c478d..c59e43a 100644
--- a/src/racoon/kmpstat.c
+++ b/src/racoon/kmpstat.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: kmpstat.c,v 1.7 2010/11/12 09:08:26 tteras Exp $	*/
+/*	$NetBSD: kmpstat.c,v 1.4.6.2 2007/11/06 16:41:33 vanhu Exp $	*/
 
 /*	$KAME: kmpstat.c,v 1.33 2004/08/16 08:20:28 itojun Exp $	*/
 
@@ -138,7 +138,7 @@
 {
 	struct admin_com h, *com;
 	caddr_t buf;
-	int len, rlen;
+	int len;
 	int l = 0;
 	caddr_t p;
 
@@ -153,25 +153,19 @@
 	if (len < sizeof(h))
 		goto bad1;
 
-	if (h.ac_errno && !(h.ac_cmd & ADMIN_FLAG_LONG_REPLY)) {
+	if (h.ac_errno) {
 		errno = h.ac_errno;
 		goto bad1;
 	}
 
-	/* real length */
-	if (h.ac_cmd & ADMIN_FLAG_LONG_REPLY)
-		rlen = ((u_int32_t)h.ac_len) + (((u_int32_t)h.ac_len_high) << 16);
-	else
-		rlen = h.ac_len;
-
 	/* allocate buffer */
-	if ((*combufp = vmalloc(rlen)) == NULL)
+	if ((*combufp = vmalloc(h.ac_len)) == NULL)
 		goto bad1;
 
 	/* read real message */
 	p = (*combufp)->v;
-	while (l < rlen) {
-		if ((len = recv(so, p, rlen - l, 0)) < 0) {
+	while (l < len) {
+		if ((len = recv(so, p, h.ac_len, 0)) < 0) {
 			perror("recv");
 			goto bad2;
 		}
diff --git a/src/racoon/localconf.c b/src/racoon/localconf.c
index a512953..ede1d9b 100644
--- a/src/racoon/localconf.c
+++ b/src/racoon/localconf.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: localconf.c,v 1.7 2008/12/23 14:04:42 tteras Exp $	*/
+/*	$NetBSD: localconf.c,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /*	$KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane Exp $	*/
 
@@ -85,14 +85,18 @@
 	int i;
 
 	setdefault();
-	myaddr_flush();
-
+	clear_myaddr(&lcconf->myaddrs);
 	for (i = 0; i < LC_PATHTYPE_MAX; i++) {
 		if (lcconf->pathinfo[i]) {
 			racoon_free(lcconf->pathinfo[i]);
 			lcconf->pathinfo[i] = NULL;
 		}
 	}
+	for (i = 0; i < LC_IDENTTYPE_MAX; i++) {
+		if (lcconf->ident[i])
+			vfree(lcconf->ident[i]);
+		lcconf->ident[i] = NULL;
+	}
 }
 
 static void
@@ -101,6 +105,7 @@
 	lcconf->uid = 0;
 	lcconf->gid = 0;
 	lcconf->chroot = NULL;
+	lcconf->autograbaddr = 1;
 	lcconf->port_isakmp = PORT_ISAKMP;
 	lcconf->port_isakmp_natt = PORT_ISAKMP_NATT;
 	lcconf->default_af = AF_INET;
@@ -119,7 +124,6 @@
 	lcconf->complex_bundle = TRUE; /*XXX FALSE;*/
 	lcconf->gss_id_enc = LC_GSSENC_UTF16LE; /* Windows compatibility */
 	lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;
-	lcconf->pfkey_buffer_size = LC_DEFAULT_PFKEY_BUFFER_SIZE;
 }
 
 /*
@@ -336,12 +340,21 @@
 	int f;
 {
 	static u_int16_t s_port_isakmp;
+#ifdef ENABLE_ADMINPORT
+	static u_int16_t s_port_admin;
+#endif
 
 	/* 0: save, 1: restore */
 	if (f) {
 		lcconf->port_isakmp = s_port_isakmp;
+#ifdef ENABLE_ADMINPORT
+		lcconf->port_admin = s_port_admin;
+#endif
 	} else {
 		s_port_isakmp = lcconf->port_isakmp;
+#ifdef ENABLE_ADMINPORT
+		s_port_admin = lcconf->port_admin;
+#endif
 	}
 }
 
diff --git a/src/racoon/localconf.h b/src/racoon/localconf.h
index 04ac8e4..f7cf33a 100644
--- a/src/racoon/localconf.h
+++ b/src/racoon/localconf.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: localconf.h,v 1.7 2008/12/23 14:04:42 tteras Exp $	*/
+/*	$NetBSD: localconf.h,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
 
 /* Id: localconf.h,v 1.13 2005/11/06 18:13:18 monas Exp */
 
@@ -57,10 +57,11 @@
 #define LC_DEFAULT_RETRY_CHECKPH1	30
 #define LC_DEFAULT_WAIT_PH2COMPLETE	30
 #define LC_DEFAULT_NATT_KA_INTERVAL	20
-#define LC_DEFAULT_PFKEY_BUFFER_SIZE	0
 
 #define LC_DEFAULT_SECRETSIZE	16	/* 128 bits */
 
+#define LC_IDENTTYPE_MAX	5	/* XXX */
+
 #define	LC_GSSENC_UTF16LE	0	/* GSS ID in UTF-16LE */
 #define	LC_GSSENC_LATIN1	1	/* GSS ID in ISO-Latin-1 */
 #define	LC_GSSENC_MAX		2
@@ -73,13 +74,18 @@
 	char *chroot;			/* chroot path */
 	u_int16_t port_isakmp;		/* port for isakmp as default */
 	u_int16_t port_isakmp_natt;	/* port for NAT-T use */
+	u_int16_t port_admin;		/* port for admin */
 	int default_af;			/* default address family */
 
 	int sock_admin;
 	int sock_pfkey;
 	int rtsock;			/* routing socket */
 
+	int autograbaddr;
+	struct myaddrs *myaddrs;
+
 	char *pathinfo[LC_PATHTYPE_MAX];
+	vchar_t *ident[LC_IDENTTYPE_MAX]; /* base of Identifier payload. */
 
 	int pad_random;
 	int pad_randomlen;
@@ -112,7 +118,6 @@
 		 */
 
 	int gss_id_enc;			/* GSS ID encoding to use */
-	int pfkey_buffer_size;		/* Set socket buffer size for pfkey */
 };
 
 extern struct localconf *lcconf;
diff --git a/src/racoon/main.c b/src/racoon/main.c
index ab71b3e..094026e 100644
--- a/src/racoon/main.c
+++ b/src/racoon/main.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.12 2009/01/26 18:13:06 tteras Exp $	*/
+/*	$NetBSD: main.c,v 1.6.6.2 2008/11/27 15:25:26 vanhu Exp $	*/
 
 /* Id: main.c,v 1.25 2006/06/20 20:31:34 manubsd Exp */
 
@@ -66,6 +66,12 @@
 
 #include "cfparse_proto.h"
 #include "isakmp_var.h"
+#ifdef ENABLE_HYBRID
+#include <resolv.h>
+#include "isakmp.h"
+#include "isakmp_xauth.h"
+#include "isakmp_cfg.h"
+#endif
 #include "remoteconf.h"
 #include "localconf.h"
 #include "session.h"
@@ -78,10 +84,10 @@
 
 #include "package_version.h"
 
-int dump_config = 0;	/* dump parsed config file. */
 int f_local = 0;	/* local test mode.  behave like a wall. */
 int vflag = 1;		/* for print-isakmp.c */
 static int loading_sa = 0;	/* install sa when racoon boots up. */
+static int dump_config = 0;	/* dump parsed config file. */
 
 #ifdef TOP_PACKAGE
 static char version[] = "@(#)" TOP_PACKAGE_STRING " (" TOP_PACKAGE_URL ")";
@@ -89,77 +95,197 @@
 static char version[] = "@(#) racoon / IPsec-tools";
 #endif /* TOP_PACKAGE */
 
-static void
-print_version()
+int main __P((int, char **));
+static void usage __P((void));
+static void parse __P((int, char **));
+#if 0
+static void cleanup_pidfile __P((void));
+#endif
+
+void
+usage()
 {
-	printf("%s\n"
-	       "\n"
-	       "Compiled with:\n"
-	       "- %s (http://www.openssl.org/)\n"
+	printf("usage: racoon [-BdFv%s] %s[-f (file)] [-l (file)] [-p (port)]\n",
 #ifdef INET6
-	       "- IPv6 support\n"
-#endif
-#ifdef ENABLE_DPD
-	       "- Dead Peer Detection\n"
-#endif
-#ifdef ENABLE_FRAG
-	       "- IKE fragmentation\n"
-#endif
-#ifdef ENABLE_HYBRID
-	       "- Hybrid authentication\n"
-#endif
-#ifdef ENABLE_GSSAPI
-	       "- GSS-API authentication\n"
-#endif
-#ifdef ENABLE_NATT
-	       "- NAT Traversal\n"
-#endif
-#ifdef ENABLE_STATS
-	       "- Timing statistics\n"
+		"46",
+#else
+		"",
 #endif
 #ifdef ENABLE_ADMINPORT
-	       "- Admin port\n"
+		"[-a (port)] "
+#else
+		""
 #endif
-#ifdef HAVE_CLOCK_MONOTONIC
-	       "- Monotonic clock\n"
+		);
+	printf("   -B: install SA to the kernel from the file "
+		"specified by the configuration file.\n");
+	printf("   -d: debug level, more -d will generate more debug message.\n");
+	printf("   -C: dump parsed config file.\n");
+	printf("   -L: include location in debug messages\n");
+	printf("   -F: run in foreground, do not become daemon.\n");
+	printf("   -v: be more verbose\n");
+#ifdef INET6
+	printf("   -4: IPv4 mode.\n");
+	printf("   -6: IPv6 mode.\n");
 #endif
+#ifdef ENABLE_ADMINPORT
+	printf("   -a: port number for admin port.\n");
+#endif
+	printf("   -f: pathname for configuration file.\n");
+	printf("   -l: pathname for log file.\n");
+	printf("   -p: port number for isakmp (default: %d).\n", PORT_ISAKMP);
+	printf("   -P: port number for NAT-T (default: %d).\n", PORT_ISAKMP_NATT);
+	exit(1);
+}
+
+int
+main(ac, av)
+	int ac;
+	char **av;
+{
+	int error;
+
+	if (geteuid() != 0) {
+		errx(1, "must be root to invoke this program.");
+		/* NOTREACHED*/
+	}
+
+	/*
+	 * Don't let anyone read files I write.  Although some files (such as
+	 * the PID file) can be other readable, we dare to use the global mask,
+	 * because racoon uses fopen(3), which can't specify the permission
+	 * at the creation time.
+	 */
+	umask(077);
+	if (umask(077) != 077) {
+		errx(1, "could not set umask");
+		/* NOTREACHED*/
+	}
+
+#ifdef DEBUG_RECORD_MALLOCATION
+	DRM_init();
+#endif
+
 #ifdef HAVE_SECCTX
-	       "- Security context\n"
+	init_avc();
 #endif
-	       "\n",
-	       version,
-	       eay_version());
+	eay_init();
+	initlcconf();
+	initrmconf();
+	oakley_dhinit();
+	compute_vendorids();
+
+	parse(ac, av);
+
+	ploginit();
+
+	plog(LLV_INFO, LOCATION, NULL, "%s\n", version);
+	plog(LLV_INFO, LOCATION, NULL, "@(#)"
+	    "This product linked %s (http://www.openssl.org/)"
+	    "\n", eay_version());
+	plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", 
+	    lcconf->racoon_conf);
+
+	if (pfkey_init() < 0) {
+		errx(1, "something error happened "
+			"while pfkey initializing.");
+		/* NOTREACHED*/
+	}
+
+#ifdef ENABLE_HYBRID
+	if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD))
+		errx(1, "could not initialize ISAKMP mode config structures");
+#endif
+
+#ifdef HAVE_LIBLDAP
+	if (xauth_ldap_init() != 0)
+		errx(1, "could not initialize libldap");
+#endif
+
+	/*
+	 * in order to prefer the parameters by command line,
+	 * saving some parameters before parsing configuration file.
+	 */
+	save_params();
+	error = cfparse();
+	if (error != 0)
+		errx(1, "failed to parse configuration file.");
+	restore_params();
+
+#ifdef ENABLE_HYBRID
+	if(isakmp_cfg_config.network4 && isakmp_cfg_config.pool_size == 0)
+		if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
+			return error;
+#endif
+
+	if (dump_config)
+		dumprmconf ();
+
+#ifdef HAVE_LIBRADIUS
+	if (xauth_radius_init() != 0) {
+		errx(1, "could not initialize libradius");
+		/* NOTREACHED*/
+	}
+#endif
+
+	/*
+	 * install SAs from the specified file.  If the file is not specified
+	 * by the configuration file, racoon will exit.
+	 */
+	if (loading_sa && !f_local) {
+		if (backupsa_from_file() != 0)
+			errx(1, "something error happened "
+				"SA recovering.");
+	}
+
+	if (f_foreground)
+		close(0);
+	else {
+		if (daemon(0, 0) < 0) {
+			errx(1, "failed to be daemon. (%s)",
+				strerror(errno));
+		}
+#ifndef __linux__
+		/*
+		 * In case somebody has started inetd manually, we need to
+		 * clear the logname, so that old servers run as root do not
+		 * get the user's logname..
+		 */
+		if (setlogin("") < 0) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"cannot clear logname: %s\n", strerror(errno));
+			/* no big deal if it fails.. */
+		}
+#endif
+		if (!f_local) {
+#if 0
+			if (atexit(cleanup_pidfile) < 0) {
+				plog(LLV_ERROR, LOCATION, NULL,
+					"cannot register pidfile cleanup");
+			}
+#endif
+		}
+	}
+
+	session();
+
 	exit(0);
 }
 
+#if 0
 static void
-usage()
+cleanup_pidfile()
 {
-	printf("usage: racoon [-BdFv"
-#ifdef INET6
-		"46"
-#endif
-		"] [-f (file)] [-l (file)] [-p (port)] [-P (natt port)]\n"
-		"   -B: install SA to the kernel from the file "
-		"specified by the configuration file.\n"
-		"   -d: debug level, more -d will generate more debug message.\n"
-		"   -C: dump parsed config file.\n"
-		"   -L: include location in debug messages\n"
-		"   -F: run in foreground, do not become daemon.\n"
-		"   -v: be more verbose\n"
-		"   -V: print version and exit\n"
-#ifdef INET6
-		"   -4: IPv4 mode.\n"
-		"   -6: IPv6 mode.\n"
-#endif
-		"   -f: pathname for configuration file.\n"
-		"   -l: pathname for log file.\n"
-		"   -p: port number for isakmp (default: %d).\n"
-		"   -P: port number for NAT-T (default: %d).\n"
-		"\n",
-		PORT_ISAKMP, PORT_ISAKMP_NATT);
-	exit(1);
+	pid_t p = getpid();
+
+	/* if it's not child process, clean everything */
+	if (racoon_pid == p) {
+		const char *pid_file = _PATH_VARRUN "racoon.pid";
+
+		(void) unlink(pid_file);
+	}
 }
+#endif
 
 static void
 parse(ac, av)
@@ -179,7 +305,7 @@
 	else
 		pname = *av;
 
-	while ((c = getopt(ac, av, "dLFp:P:f:l:vVZBC"
+	while ((c = getopt(ac, av, "dLFp:P:a:f:l:vZBC"
 #ifdef YYDEBUG
 			"y"
 #endif
@@ -204,6 +330,15 @@
 		case 'P':
 			lcconf->port_isakmp_natt = atoi(optarg);
 			break;
+		case 'a':
+#ifdef ENABLE_ADMINPORT
+			lcconf->port_admin = atoi(optarg);
+			break;
+#else
+			fprintf(stderr, "%s: the option is disabled "
+			    "in the configuration\n", pname);
+			exit(1);
+#endif
 		case 'f':
 			lcconf->racoon_conf = optarg;
 			break;
@@ -213,9 +348,6 @@
 		case 'v':
 			vflag++;
 			break;
-		case 'V':
-			print_version();
-			break;
 		case 'Z':
 			/*
 			 * only local test.
@@ -261,89 +393,6 @@
 		usage();
 		/* NOTREACHED */
 	}
+
+	return;
 }
-
-int
-main(ac, av)
-	int ac;
-	char **av;
-{
-	int error;
-
-	initlcconf();
-	parse(ac, av);
-
-	if (geteuid() != 0) {
-		errx(1, "must be root to invoke this program.");
-		/* NOTREACHED*/
-	}
-
-	/*
-	 * Don't let anyone read files I write.  Although some files (such as
-	 * the PID file) can be other readable, we dare to use the global mask,
-	 * because racoon uses fopen(3), which can't specify the permission
-	 * at the creation time.
-	 */
-	umask(077);
-	if (umask(077) != 077) {
-		errx(1, "could not set umask");
-		/* NOTREACHED*/
-	}
-
-#ifdef DEBUG_RECORD_MALLOCATION
-	DRM_init();
-#endif
-
-#ifdef HAVE_SECCTX
-	init_avc();
-#endif
-	eay_init();
-	initrmconf();
-	oakley_dhinit();
-	compute_vendorids();
-
-	ploginit();
-
-	plog(LLV_INFO, LOCATION, NULL, "%s\n", version);
-	plog(LLV_INFO, LOCATION, NULL, "@(#)"
-	    "This product linked %s (http://www.openssl.org/)"
-	    "\n", eay_version());
-	plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", 
-	    lcconf->racoon_conf);
-
-	/*
-	 * install SAs from the specified file.  If the file is not specified
-	 * by the configuration file, racoon will exit.
-	 */
-	if (loading_sa && !f_local) {
-		if (backupsa_from_file() != 0)
-			errx(1, "something error happened "
-				"SA recovering.");
-	}
-
-	if (f_foreground)
-		close(0);
-	else {
-		if (daemon(0, 0) < 0) {
-			errx(1, "failed to be daemon. (%s)",
-				strerror(errno));
-		}
-#ifndef __linux__
-		/*
-		 * In case somebody has started inetd manually, we need to
-		 * clear the logname, so that old servers run as root do not
-		 * get the user's logname..
-		 */
-		if (setlogin("") < 0) {
-			plog(LLV_ERROR, LOCATION, NULL,
-				"cannot clear logname: %s\n", strerror(errno));
-			/* no big deal if it fails.. */
-		}
-#endif
-	}
-
-	session();
-
-	return 0;
-}
-
diff --git a/src/racoon/misc.c b/src/racoon/misc.c
index 91b8e77..4daa0ed 100644
--- a/src/racoon/misc.c
+++ b/src/racoon/misc.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: misc.c,v 1.6 2008/07/15 00:47:09 mgrooms Exp $	*/
+/*	$NetBSD: misc.c,v 1.4.6.1 2008/07/15 00:55:48 mgrooms Exp $	*/
 
 /*	$KAME: misc.c,v 1.23 2001/08/16 14:37:29 itojun Exp $	*/
 
@@ -44,7 +44,6 @@
 #include <errno.h>
 #include <syslog.h>
 #include <ctype.h>
-#include <fcntl.h>
 
 #include "var.h"
 #include "misc.h"
@@ -155,16 +154,6 @@
 }
 
 /*
- * set the close-on-exec flag for file descriptor fd.
- */
-void
-close_on_exec(fd)
-	int fd;
-{
-	fcntl(fd, F_SETFD, FD_CLOEXEC);
-}
-
-/*
  * calculate the difference between two times.
  * t1: start
  * t2: end
diff --git a/src/racoon/misc.h b/src/racoon/misc.h
index 3e758d9..66e42b1 100644
--- a/src/racoon/misc.h
+++ b/src/racoon/misc.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: misc.h,v 1.6 2008/07/15 00:47:09 mgrooms Exp $	*/
+/*	$NetBSD: misc.h,v 1.4.6.1 2008/07/15 00:55:48 mgrooms Exp $	*/
 
 /* Id: misc.h,v 1.9 2006/04/06 14:00:06 manubsd Exp */
 
@@ -50,7 +50,6 @@
 struct timeval;
 extern double timedelta __P((struct timeval *, struct timeval *));
 char *strdup __P((const char *));
-extern void close_on_exec __P((int fd));
 
 #if defined(__APPLE__) && defined(__MACH__)
 #define RACOON_TAILQ_FOREACH_REVERSE(var, head, headname ,field)	\
diff --git a/src/racoon/nattraversal.c b/src/racoon/nattraversal.c
index b04cc1b..9fd4bcd 100644
--- a/src/racoon/nattraversal.c
+++ b/src/racoon/nattraversal.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: nattraversal.c,v 1.14 2011/03/14 17:18:13 tteras Exp $	*/
+/*	$NetBSD: nattraversal.c,v 1.6.6.2 2009/05/18 17:01:07 tteras Exp $	*/
 
 /*
  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
@@ -77,7 +77,6 @@
 };
 
 static TAILQ_HEAD(_natt_ka_addrs, natt_ka_addrs) ka_tree;
-static struct sched sc_natt = SCHED_INITIALIZER();
 
 /*
  * check if the given vid is NAT-T.
@@ -127,14 +126,10 @@
   char *ptr;
   void *addr_ptr, *addr_port;
   size_t buf_size, addr_size;
-  int natt_force = 0;
-
-  if (iph1->rmconf != NULL && iph1->rmconf->nat_traversal == NATT_FORCE)
-	  natt_force = 1;
 
   plog (LLV_INFO, LOCATION, addr, "Hashing %s with algo #%d %s\n",
 	saddr2str(addr), iph1->approval->hashtype, 
-	natt_force?"(NAT-T forced)":"");
+	(iph1->rmconf->nat_traversal == NATT_FORCE)?"(NAT-T forced)":"");
   
   if (addr->sa_family == AF_INET) {
     addr_size = sizeof (struct in_addr);	/* IPv4 address */
@@ -168,7 +163,7 @@
   ptr += sizeof (cookie_t);
   
   /* Copy-in Address (or zeroes if NATT_FORCE) */
-  if (natt_force)
+  if (iph1->rmconf->nat_traversal == NATT_FORCE)
     memset (ptr, 0, addr_size);
   else
     memcpy (ptr, addr_ptr, addr_size);
@@ -191,8 +186,7 @@
   u_int32_t flag;
   int verified = 0;
 
-  if (iph1->rmconf != NULL &&
-      iph1->rmconf->nat_traversal == NATT_FORCE)
+  if (iph1->rmconf->nat_traversal == NATT_FORCE)
     return verified;
 
   if (natd_seq == 0) {
@@ -308,28 +302,9 @@
 	natt_keepalive_add_ph1 (iph1);
 }
 
-static int
-natt_is_enabled (struct remoteconf *rmconf, void *args)
-{
-  if (rmconf->nat_traversal)
-    return 1;
-  return 0;
-}
-
 void
 natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric)
 {
-  if (iph1->rmconf == NULL) {
-    /* Check if any candidate remote conf allows nat-t */
-    struct rmconfselector rmconf;
-    rmconf_selector_from_ph1(&rmconf, iph1);
-    if (enumrmconf(&rmconf, natt_is_enabled, NULL) == 0)
-      return;
-  } else {
-    if (!iph1->rmconf->nat_traversal)
-      return;
-  }
-
   if (! iph1->natt_options)
     iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options));
 
@@ -355,7 +330,7 @@
 
 /* NAT keepalive functions */
 static void
-natt_keepalive_send (struct sched *param)
+natt_keepalive_send (void *param)
 {
   struct natt_ka_addrs	*ka, *next = NULL;
   char keepalive_packet[] = { 0xff };
@@ -365,7 +340,7 @@
   for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) {
     next = TAILQ_NEXT(ka, chain);
     
-    s = myaddr_getfd(ka->src);
+    s = getsockmyaddr(ka->src);
     if (s == -1) {
       natt_keepalive_delete(ka);
       continue;
@@ -379,7 +354,7 @@
 	   strerror (errno));
   }
   
-  sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send);
+  sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL);
 }
 
 void
@@ -389,7 +364,7 @@
 
   /* To disable sending KAs set natt_ka_interval=0 */
   if (lcconf->natt_ka_interval > 0)
-    sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send);
+    sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL);
 }
 
 int
@@ -398,8 +373,8 @@
   struct natt_ka_addrs *ka = NULL, *new_addr;
   
   TAILQ_FOREACH (ka, &ka_tree, chain) {
-    if (cmpsaddr(ka->src, src) == CMPSADDR_MATCH &&
-	cmpsaddr(ka->dst, dst) == CMPSADDR_MATCH) {
+    if (cmpsaddrstrict(ka->src, src) == 0 && 
+	cmpsaddrstrict(ka->dst, dst) == 0) {
       ka->in_use++;
       plog (LLV_INFO, LOCATION, NULL, "KA found: %s (in_use=%u)\n",
 	    saddr2str_fromto("%s->%s", src, dst), ka->in_use);
@@ -462,8 +437,8 @@
     plog (LLV_DEBUG, LOCATION, NULL, "KA tree dump: %s (in_use=%u)\n",
 	  saddr2str_fromto("%s->%s", src, dst), ka->in_use);
 
-    if (cmpsaddr(ka->src, src) == CMPSADDR_MATCH &&
-	cmpsaddr(ka->dst, dst) == CMPSADDR_MATCH &&
+    if (cmpsaddrstrict(ka->src, src) == 0 && 
+	cmpsaddrstrict(ka->dst, dst) == 0 &&
 	-- ka->in_use <= 0) {
 
       plog (LLV_DEBUG, LOCATION, NULL, "KA removing this one...\n");
@@ -476,16 +451,16 @@
   }
 }
 
-static int
+static struct remoteconf *
 natt_enabled_in_rmconf_stub (struct remoteconf *rmconf, void *data)
 {
-  return rmconf->nat_traversal ? 1 : 0;
+  return (rmconf->nat_traversal ? rmconf : NULL);
 }
 
 int
 natt_enabled_in_rmconf ()
 {
-  return enumrmconf(NULL, natt_enabled_in_rmconf_stub, NULL) != 0;
+  return foreachrmconf (natt_enabled_in_rmconf_stub, NULL) != NULL;
 }
 
 
diff --git a/src/racoon/nattraversal.h b/src/racoon/nattraversal.h
index 3b0b03b..cec5815 100644
--- a/src/racoon/nattraversal.h
+++ b/src/racoon/nattraversal.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: nattraversal.h,v 1.7 2010/09/22 07:34:51 vanhu Exp $	*/
+/*	$NetBSD: nattraversal.h,v 1.6 2006/09/09 16:22:09 manu Exp $	*/
 
 /*
  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
@@ -42,12 +42,12 @@
 #define	NAT_KA_QUEUED		(1L<<4)
 #define	NAT_ADD_NON_ESP_MARKER	(1L<<5)
 
-#define	NATT_AVAILABLE(_ph1)	((_ph1)->natt_flags & NAT_ANNOUNCED)
+#define	NATT_AVAILABLE(ph1)	((iph1)->natt_flags & NAT_ANNOUNCED)
 
 #define	NAT_DETECTED	(NAT_DETECTED_ME | NAT_DETECTED_PEER)
 
 #define	NON_ESP_MARKER_LEN	sizeof(u_int32_t)
-#define	NON_ESP_MARKER_USE(_ph1)	((_ph1)->natt_flags & NAT_ADD_NON_ESP_MARKER)
+#define	NON_ESP_MARKER_USE(iph1)	((iph1)->natt_flags & NAT_ADD_NON_ESP_MARKER)
 
 /* These are the values from parsing "remote {}" 
    block of the config file. */
diff --git a/src/racoon/oakley.c b/src/racoon/oakley.c
index 4a106df..183ac2f 100644
--- a/src/racoon/oakley.c
+++ b/src/racoon/oakley.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: oakley.c,v 1.22 2011/03/17 14:42:58 vanhu Exp $	*/
+/*	$NetBSD: oakley.c,v 1.9.6.4 2009/08/13 09:18:45 vanhu Exp $	*/
 
 /* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */
 
@@ -123,63 +123,13 @@
 
 static int oakley_check_dh_pub __P((vchar_t *, vchar_t **));
 static int oakley_compute_keymat_x __P((struct ph2handle *, int, int));
+static int get_cert_fromlocal __P((struct ph1handle *, int));
+static int get_plainrsa_fromlocal __P((struct ph1handle *, int));
 static int oakley_check_certid __P((struct ph1handle *iph1));
 static int check_typeofcertname __P((int, int));
+static cert_t *save_certbuf __P((struct isakmp_gen *));
+static cert_t *save_certx509 __P((X509 *));
 static int oakley_padlen __P((int, int));
-static int get_plainrsa_fromlocal __P((struct ph1handle *, int));
-
-int oakley_get_certtype(cert)
-	vchar_t *cert;
-{
-	if (cert == NULL)
-		return ISAKMP_CERT_NONE;
-
-	return cert->v[0];
-}
-
-static vchar_t *
-dump_isakmp_payload(gen)
-	struct isakmp_gen *gen;
-{
-	vchar_t p;
-
-	if (ntohs(gen->len) <= sizeof(*gen)) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "Len is too small !!.\n");
-		return NULL;
-	}
-
-	p.v = (caddr_t) (gen + 1);
-	p.l = ntohs(gen->len) - sizeof(*gen);
-
-	return vdup(&p);
-}
-
-static vchar_t *
-dump_x509(cert)
-	X509 *cert;
-{
-	vchar_t *pl;
-	u_char *bp;
-	int len;
-
-	len = i2d_X509(cert, NULL);
-
-	pl = vmalloc(len + 1);
-	if (pl == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "Failed to copy CERT from packet.\n");
-		return NULL;
-	}
-
-	pl->v[0] = ISAKMP_CERT_X509SIGN;
-	bp = (u_char *) &pl->v[1];
-	i2d_X509(cert, &bp);
-
-	return pl;
-}
-
-
 
 int
 oakley_get_defaultlifetime()
@@ -468,7 +418,7 @@
 	res = alg_oakley_hashdef_one(type, buf);
 	if (res == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"invalid hash algorithm %d.\n", type);
+			"invalid hash algoriym %d.\n", type);
 		return NULL;
 	}
 
@@ -908,7 +858,7 @@
 		+ (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
 		if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
 			bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
 			len += bp->l;
@@ -969,7 +919,7 @@
 	p += bp->l;
 
 #ifdef HAVE_GSSAPI
-	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
+	if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
 		if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
 			bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
 			memcpy(p, bp->v, bp->l);
@@ -1030,7 +980,7 @@
 		return NULL;
 	}
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
@@ -1039,7 +989,7 @@
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 #endif
 		if (iph1->skeyid == NULL) {
@@ -1171,7 +1121,7 @@
 		return NULL;
 	}
 
-	switch (iph1->approval->authmethod) {
+	switch(AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
 #ifdef ENABLE_HYBRID
@@ -1183,7 +1133,7 @@
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 #endif
 		break;
 	default:
@@ -1299,10 +1249,10 @@
 	gettimeofday(&start, NULL);
 #endif
 
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 #endif
 		/* validate HASH */
@@ -1315,7 +1265,7 @@
 			return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
 		}
 #ifdef ENABLE_HYBRID
-		if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I &&
+		if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I &&
 		    ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
 		{
 			plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
@@ -1373,7 +1323,7 @@
 #endif
 	    {
 		int error = 0;
-		int certtype;
+		int certtype = 0;
 
 		/* validation */
 		if (iph1->id_p == NULL) {
@@ -1391,104 +1341,132 @@
 		plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
 
 		/* get peer's cert */
-		certtype = oakley_get_certtype(iph1->rmconf->peerscert);
-		switch (certtype) {
-		case ISAKMP_CERT_NONE:
-			/* expect to receive one from peer */
+		switch (iph1->rmconf->getcert_method) {
+		case ISAKMP_GETCERT_PAYLOAD:
 			if (iph1->cert_p == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
-				     "no peer's CERT payload found.\n");
+					"no peer's CERT payload found.\n");
 				return ISAKMP_INTERNAL_ERROR;
 			}
-			/* verify the cert if needed */
-			if (!iph1->rmconf->verify_cert)
-				break;
-
-			switch (oakley_get_certtype(iph1->cert_p)) {
-			case ISAKMP_CERT_X509SIGN: {
-				char path[MAXPATHLEN];
-				char *ca;
-
-				if (iph1->rmconf->cacertfile != NULL) {
-					getpathname(path, sizeof(path),
-						    LC_PATHTYPE_CERT,
-						    iph1->rmconf->cacertfile);
-					ca = path;
-				} else {
-					ca = NULL;
-				}
-
-				error = eay_check_x509cert(
-					iph1->cert_p,
-					lcconf->pathinfo[LC_PATHTYPE_CERT],
-					ca, 0);
-				break;
-				}
-			default:
-				plog(LLV_ERROR, LOCATION, NULL,
-					"peers_cert certtype %d was not expected\n",
-					certtype);
-				return ISAKMP_INTERNAL_ERROR;
-			}
-
-			if (error != 0) {
-				plog(LLV_ERROR, LOCATION, NULL,
-				     "the peer's certificate is not verified.\n");
-				return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
-			}
 			break;
-		case ISAKMP_CERT_X509SIGN:
-			if (iph1->rmconf->peerscert == NULL) {
+		case ISAKMP_GETCERT_LOCALFILE:
+			switch (iph1->rmconf->certtype) {
+				case ISAKMP_CERT_X509SIGN:
+					if (iph1->rmconf->peerscertfile == NULL) {
+						plog(LLV_ERROR, LOCATION, NULL,
+							"no peer's CERT file found.\n");
+						return ISAKMP_INTERNAL_ERROR;
+					}
+
+					/* don't use cached cert */
+					if (iph1->cert_p != NULL) {
+						oakley_delcert(iph1->cert_p);
+						iph1->cert_p = NULL;
+					}
+
+					error = get_cert_fromlocal(iph1, 0);
+#ifdef ANDROID_PATCHED
+					if (!error)
+						break;
+				default:
+					return ISAKMP_INTERNAL_ERROR;
+#else
+					break;
+
+				case ISAKMP_CERT_PLAINRSA:
+					error = get_plainrsa_fromlocal(iph1, 0);
+					break;
+			}
+			if (error)
+				return ISAKMP_INTERNAL_ERROR;
+			break;
+		case ISAKMP_GETCERT_DNS:
+			if (iph1->rmconf->peerscertfile != NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
-				     "no peer's CERT file found.\n");
+					"why peer's CERT file is defined "
+					"though getcert method is dns ?\n");
 				return ISAKMP_INTERNAL_ERROR;
 			}
-			/* don't use received cert */
+
+			/* don't use cached cert */
 			if (iph1->cert_p != NULL) {
-				vfree(iph1->cert_p);
-				iph1->cert_p = NULL;
-			}
-			/* copy from remoteconf instead */
-			iph1->cert_p = vdup(iph1->rmconf->peerscert);
-			break;
-#ifndef ANDROID_PATCHED
-		case ISAKMP_CERT_PLAINRSA:
-			if (get_plainrsa_fromlocal(iph1, 0))
-				return ISAKMP_INTERNAL_ERROR;
-			break;
-		case ISAKMP_CERT_DNS:
-			/* don't use received cert */
-			if (iph1->cert_p != NULL) {
-				vfree(iph1->cert_p);
+				oakley_delcert(iph1->cert_p);
 				iph1->cert_p = NULL;
 			}
 
 			iph1->cert_p = dnssec_getcert(iph1->id_p);
 			if (iph1->cert_p == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL,
-				     "no CERT RR found.\n");
+					"no CERT RR found.\n");
 				return ISAKMP_INTERNAL_ERROR;
+#endif
 			}
 			break;
-#endif
 		default:
 			plog(LLV_ERROR, LOCATION, NULL,
-			     "invalid certificate type: %d\n",
-			     oakley_get_certtype(iph1->rmconf->peerscert));
+				"invalid getcert_mothod: %d\n",
+				iph1->rmconf->getcert_method);
 			return ISAKMP_INTERNAL_ERROR;
 		}
 
 		/* compare ID payload and certificate name */
-		if ((error = oakley_check_certid(iph1)) != 0)
+		if (iph1->rmconf->verify_cert &&
+		    (error = oakley_check_certid(iph1)) != 0)
 			return error;
 
-		/* Generate a warning if verify_cert */
-		if (iph1->rmconf->verify_cert) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-			     "CERT validated\n");
-		} else {
+		/* verify certificate */
+		if (iph1->rmconf->verify_cert
+		 && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) {
+			certtype = iph1->rmconf->certtype;
+#ifdef ENABLE_HYBRID
+			switch (AUTHMETHOD(iph1)) {
+			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+				certtype = iph1->cert_p->type;
+				break;
+			default:
+				break;
+			}
+#endif
+			switch (certtype) {
+			case ISAKMP_CERT_X509SIGN: {
+				char path[MAXPATHLEN];
+				char *ca;
+
+				if (iph1->rmconf->cacertfile != NULL) {
+					getpathname(path, sizeof(path), 
+					    LC_PATHTYPE_CERT, 
+					    iph1->rmconf->cacertfile);
+					ca = path;
+				} else {
+					ca = NULL;
+				}
+
+				error = eay_check_x509cert(&iph1->cert_p->cert,
+					lcconf->pathinfo[LC_PATHTYPE_CERT], 
+					ca, 0);
+				break;
+			}
+			
+			default:
+				plog(LLV_ERROR, LOCATION, NULL,
+					"no supported certtype %d\n", certtype);
+				return ISAKMP_INTERNAL_ERROR;
+			}
+			if (error != 0) {
+				plog(LLV_ERROR, LOCATION, NULL,
+					"the peer's certificate is not verified.\n");
+				return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
+			}
+		}
+	
+		/* Generate a warning if verify_cert == 0
+		 */
+		if (iph1->rmconf->verify_cert){
+			plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n");
+		}else{
 			plog(LLV_WARNING, LOCATION, NULL,
-			     "CERT validation disabled by configuration\n");
+				"CERT validation disabled by configuration\n");
 		}
 
 		/* compute hash */
@@ -1511,30 +1489,38 @@
 		if (my_hash == NULL)
 			return ISAKMP_INTERNAL_ERROR;
 
+
+		certtype = iph1->rmconf->certtype;
+#ifdef ENABLE_HYBRID
+		switch (AUTHMETHOD(iph1)) {
+		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+			certtype = iph1->cert_p->type;
+			break;
+		default:
+			break;
+		}
+#endif
 		/* check signature */
-		certtype = oakley_get_certtype(iph1->cert_p);
-		if (certtype == ISAKMP_CERT_NONE)
-			certtype = oakley_get_certtype(iph1->rmconf->peerscert);
 		switch (certtype) {
 		case ISAKMP_CERT_X509SIGN:
 		case ISAKMP_CERT_DNS:
 			error = eay_check_x509sign(my_hash,
-						   iph1->sig_p,
-						   iph1->cert_p);
+					iph1->sig_p,
+					&iph1->cert_p->cert);
 			break;
 #ifndef ANDROID_PATCHED
 		case ISAKMP_CERT_PLAINRSA:
 			iph1->rsa_p = rsa_try_check_rsasign(my_hash,
 					iph1->sig_p, iph1->rsa_candidates);
 			error = iph1->rsa_p ? 0 : -1;
-			genlist_free(iph1->rsa_candidates, NULL);
-			iph1->rsa_candidates = NULL;
+
 			break;
 #endif
 		default:
 			plog(LLV_ERROR, LOCATION, NULL,
-			     "cannot check signature for certtype %d\n",
-			     certtype);
+				"no supported certtype %d\n",
+				certtype);
 			vfree(my_hash);
 			return ISAKMP_INTERNAL_ERROR;
 		}
@@ -1648,26 +1634,115 @@
 oakley_getmycert(iph1)
 	struct ph1handle *iph1;
 {
-	switch (oakley_get_certtype(iph1->rmconf->mycert)) {
-	case ISAKMP_CERT_X509SIGN:
-		if (iph1->cert)
-			return 0;
-		iph1->cert = vdup(iph1->rmconf->mycert);
-		break;
+	switch (iph1->rmconf->certtype) {
+		case ISAKMP_CERT_X509SIGN:
+			if (iph1->cert)
+				return 0;
+			return get_cert_fromlocal(iph1, 1);
+
 #ifndef ANDROID_PATCHED
-	case ISAKMP_CERT_PLAINRSA:
-		if (iph1->rsa)
-			return 0;
-		return get_plainrsa_fromlocal(iph1, 1);
+		case ISAKMP_CERT_PLAINRSA:
+			if (iph1->rsa)
+				return 0;
+			return get_plainrsa_fromlocal(iph1, 1);
 #endif
-	default:
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "Unknown certtype #%d\n",
-		     oakley_get_certtype(iph1->rmconf->mycert));
-		return -1;
+
+		default:
+			plog(LLV_ERROR, LOCATION, NULL,
+			     "Unknown certtype #%d\n",
+			     iph1->rmconf->certtype);
+			return -1;
 	}
 
-	return 0;
+}
+
+/*
+ * get a CERT from local file.
+ * IN:
+ *	my != 0 my cert.
+ *	my == 0 peer's cert.
+ */
+static int
+get_cert_fromlocal(iph1, my)
+	struct ph1handle *iph1;
+	int my;
+{
+	char path[MAXPATHLEN];
+	vchar_t *cert = NULL;
+	cert_t **certpl;
+	char *certfile;
+	int error = -1;
+
+	if (my) {
+		certfile = iph1->rmconf->mycertfile;
+		certpl = &iph1->cert;
+	} else {
+		certfile = iph1->rmconf->peerscertfile;
+		certpl = &iph1->cert_p;
+	}
+	if (!certfile) {
+		plog(LLV_ERROR, LOCATION, NULL, "no CERT defined.\n");
+		return 0;
+	}
+
+	switch (iph1->rmconf->certtype) {
+	case ISAKMP_CERT_X509SIGN:
+	case ISAKMP_CERT_DNS:
+		/* make public file name */
+		getpathname(path, sizeof(path), LC_PATHTYPE_CERT, certfile);
+		cert = eay_get_x509cert(path);
+		if (cert) {
+			char *p = NULL;
+			p = eay_get_x509text(cert);
+			plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
+			racoon_free(p);
+		};
+		break;
+
+	default:
+		plog(LLV_ERROR, LOCATION, NULL,
+			"not supported certtype %d\n",
+			iph1->rmconf->certtype);
+		goto end;
+	}
+
+	if (!cert) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get %s CERT.\n",
+			my ? "my" : "peers");
+		goto end;
+	}
+
+	*certpl = oakley_newcert();
+	if (!*certpl) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get cert buffer.\n");
+		goto end;
+	}
+	(*certpl)->pl = vmalloc(cert->l + 1);
+	if ((*certpl)->pl == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get cert buffer\n");
+		oakley_delcert(*certpl);
+		*certpl = NULL;
+		goto end;
+	}
+	memcpy((*certpl)->pl->v + 1, cert->v, cert->l);
+	(*certpl)->pl->v[0] = iph1->rmconf->certtype;
+	(*certpl)->type = iph1->rmconf->certtype;
+	(*certpl)->cert.v = (*certpl)->pl->v + 1;
+	(*certpl)->cert.l = (*certpl)->pl->l - 1;
+
+	plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
+	plogdump(LLV_DEBUG, (*certpl)->pl->v, (*certpl)->pl->l);
+
+	error = 0;
+
+end:
+	if (cert != NULL)
+		vfree(cert);
+
+	return error;
 }
 
 #ifndef ANDROID_PATCHED
@@ -1733,7 +1808,7 @@
 	vchar_t *privkey = NULL;
 	int error = -1;
 
-	switch (oakley_get_certtype(iph1->rmconf->mycert)) {
+	switch (iph1->rmconf->certtype) {
 	case ISAKMP_CERT_X509SIGN:
 	case ISAKMP_CERT_DNS:
 		if (iph1->rmconf->myprivfile == NULL) {
@@ -1753,6 +1828,7 @@
 		}
 		plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
 		plogdump(LLV_DEBUG2, privkey->v, privkey->l);
+
 		iph1->sig = eay_get_x509sign(iph1->hash, privkey);
 		break;
 #ifndef ANDROID_PATCHED
@@ -1763,7 +1839,7 @@
 	default:
 		plog(LLV_ERROR, LOCATION, NULL,
 		     "Unknown certtype #%d\n",
-		     oakley_get_certtype(iph1->rmconf->mycert));
+		     iph1->rmconf->certtype);
 		goto end;
 	}
 
@@ -1797,11 +1873,8 @@
 	int idlen, type;
 	int error;
 
-	if (iph1->rmconf == NULL || iph1->rmconf->verify_cert == FALSE)
-		return 0;
-
 	if (iph1->id_p == NULL || iph1->cert_p == NULL) {
-		plog(LLV_ERROR, LOCATION, iph1->remote, "no ID nor CERT found.\n");
+		plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
 	}
 
@@ -1810,30 +1883,27 @@
 
 	switch (id_b->type) {
 	case IPSECDOI_ID_DER_ASN1_DN:
-		name = eay_get_x509asn1subjectname(iph1->cert_p);
+		name = eay_get_x509asn1subjectname(&iph1->cert_p->cert);
 		if (!name) {
-			plog(LLV_ERROR, LOCATION, iph1->remote,
+			plog(LLV_ERROR, LOCATION, NULL,
 				"failed to get subjectName\n");
 			return ISAKMP_NTYPE_INVALID_CERTIFICATE;
 		}
 		if (idlen != name->l) {
-			plog(LLV_ERROR, LOCATION, iph1->remote,
+			plog(LLV_ERROR, LOCATION, NULL,
 				"Invalid ID length in phase 1.\n");
 			vfree(name);
 			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
 		}
 		error = memcmp(id_b + 1, name->v, idlen);
+		vfree(name);
 		if (error != 0) {
-			plog(LLV_ERROR, LOCATION, iph1->remote,
+			plog(LLV_ERROR, LOCATION, NULL,
 				"ID mismatched with ASN1 SubjectName.\n");
 			plogdump(LLV_DEBUG, id_b + 1, idlen);
 			plogdump(LLV_DEBUG, name->v, idlen);
-			if (iph1->rmconf->verify_identifier) {
-				vfree(name);
-				return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
-			}
+			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
 		}
-		vfree(name);
 		return 0;
 	case IPSECDOI_ID_IPV4_ADDR:
 	case IPSECDOI_ID_IPV6_ADDR:
@@ -1848,7 +1918,7 @@
 		int pos;
 
 		for (pos = 1; ; pos++) {
-			if (eay_get_x509subjectaltname(iph1->cert_p,
+			if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
 					&altname, &type, pos) !=0) {
 				plog(LLV_ERROR, LOCATION, NULL,
 					"failed to get subjectAltName\n");
@@ -1874,11 +1944,10 @@
 		hints.ai_socktype = SOCK_RAW;
 		hints.ai_flags = AI_NUMERICHOST;
 		error = getaddrinfo(altname, NULL, &hints, &res);
-		racoon_free(altname);
-		altname = NULL;
 		if (error != 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"no proper subjectAltName.\n");
+			racoon_free(altname);
 			return ISAKMP_NTYPE_INVALID_CERTIFICATE;
 		}
 		switch (res->ai_family) {
@@ -1893,6 +1962,7 @@
 		default:
 			plog(LLV_ERROR, LOCATION, NULL,
 				"family not supported: %d.\n", res->ai_family);
+			racoon_free(altname);
 			freeaddrinfo(res);
 			return ISAKMP_NTYPE_INVALID_CERTIFICATE;
 		}
@@ -1904,8 +1974,7 @@
 				"ID mismatched with subjectAltName.\n");
 			plogdump(LLV_DEBUG, id_b + 1, idlen);
 			plogdump(LLV_DEBUG, a, idlen);
-			if (iph1->rmconf->verify_identifier)
-				return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
 		}
 		return 0;
 	}
@@ -1915,7 +1984,7 @@
 		int pos;
 
 		for (pos = 1; ; pos++) {
-			if (eay_get_x509subjectaltname(iph1->cert_p,
+			if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
 					&altname, &type, pos) != 0){
 				plog(LLV_ERROR, LOCATION, NULL,
 					"failed to get subjectAltName\n");
@@ -2009,7 +2078,7 @@
 	struct ph1handle *iph1;
 	struct isakmp_gen *gen;
 {
-	vchar_t **c;
+	cert_t **c;
 	u_int8_t type;
 	STACK_OF(X509) *certs=NULL;
 	PKCS7 *p7;
@@ -2104,7 +2173,7 @@
 			     "Trying PKCS#7 cert %d.\n", i);
 
 			/* We'll just try each cert in turn */
-			*c = dump_x509(cert);
+			*c = save_certx509(cert);
 
 			if (!*c) {
 				plog(LLV_ERROR, LOCATION, NULL,
@@ -2116,18 +2185,19 @@
 			 * XXX If verify cert is disabled, we still just take
 			 * the first certificate....
 			 */
-			if (oakley_check_certid(iph1)) {
+			if(iph1->rmconf->verify_cert &&
+			   oakley_check_certid(iph1)) {
 				plog(LLV_DEBUG, LOCATION, NULL,
 				     "Discarding CERT: does not match ID.\n");
-				vfree((*c));
+				oakley_delcert((*c));
 				*c = NULL;
 				continue;
 			}
 
 			{
-				char *p = eay_get_x509text(*c);
+				char *p = eay_get_x509text(&(*c)->cert);
 				plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
-				plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
+				plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
 				plog(LLV_DEBUG, LOCATION, NULL, "%s", 
 				     p ? p : "\n");
 				racoon_free(p);
@@ -2135,15 +2205,21 @@
 			break;
 		}
 		PKCS7_free(p7);
+
 	} else {
-		*c = dump_isakmp_payload(gen);
+		*c = save_certbuf(gen);
 		if (!*c) {
 			plog(LLV_ERROR, LOCATION, NULL,
 			     "Failed to get CERT buffer.\n");
 			return -1;
 		}
 
-		switch (type) {
+		switch ((*c)->type) {
+		case ISAKMP_CERT_DNS:
+			plog(LLV_WARNING, LOCATION, NULL,
+			     "CERT payload is unnecessary in DNSSEC. "
+			     "ignore it.\n");
+			return 0;
 		case ISAKMP_CERT_PGP:
 		case ISAKMP_CERT_X509SIGN:
 		case ISAKMP_CERT_KERBEROS:
@@ -2152,32 +2228,33 @@
 			 * XXX If verify cert is disabled, we still just take
 			 * the first certificate....
 			 */
-			if (oakley_check_certid(iph1)){
+			if(iph1->rmconf->verify_cert &&
+			   oakley_check_certid(iph1)){
 				plog(LLV_DEBUG, LOCATION, NULL,
 				     "Discarding CERT: does not match ID.\n");
-				vfree((*c));
+				oakley_delcert((*c));
 				*c = NULL;
 				return 0;
 			}
 
 			{
-				char *p = eay_get_x509text(*c);
+				char *p = eay_get_x509text(&(*c)->cert);
 				plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
-				plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
+				plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
 				plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
 				racoon_free(p);
 			}
 			break;
 		case ISAKMP_CERT_CRL:
 			plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
-			plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
+			plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
 			break;
 		case ISAKMP_CERT_X509KE:
 		case ISAKMP_CERT_X509ATTR:
 		case ISAKMP_CERT_ARL:
 		default:
 			/* XXX */
-			vfree(*c);
+			oakley_delcert((*c));
 			*c = NULL;
 			return 0;
 		}
@@ -2194,11 +2271,11 @@
 	struct ph1handle *iph1;
 	struct isakmp_gen *gen;
 {
-	vchar_t *cert;
-	vchar_t **c;
+	cert_t **c;
 	u_int8_t type;
 
 	type = *(u_int8_t *)(gen + 1) & 0xff;
+
 	switch (type) {
 	case ISAKMP_CERT_DNS:
 		plog(LLV_WARNING, LOCATION, NULL,
@@ -2224,109 +2301,119 @@
 		return -1;
 	}
 
-	/* Already found an acceptable CR? */
-	if (*c != NULL)
-		return 0;
-
-	cert = dump_isakmp_payload(gen);
-	if (cert == NULL) {
+	*c = save_certbuf(gen);
+	if (!*c) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"Failed to get CR buffer.\n");
 		return -1;
 	}
 
-	plog(LLV_DEBUG, LOCATION, NULL, "CR received:\n");
-	plogdump(LLV_DEBUG, cert->v, cert->l);
+	plog(LLV_DEBUG, LOCATION, NULL, "CR saved:\n");
+	plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
 
-	*c = cert;
-	if (resolveph1rmconf(iph1) == 0) {
-		/* Found unique match */
-		plog(LLV_DEBUG, LOCATION, NULL, "CR saved.\n");
-	} else {
-		/* Still ambiguous or matches nothing, ignore this CR */
-		*c = NULL;
-		vfree(cert);
-	}
 	return 0;
 }
 
-/*
- * Add a single CR.
- */
-struct append_cr_ctx {
-	struct ph1handle *iph1;
-	struct payload_list *plist;
-};
-
-static int
-oakley_append_rmconf_cr(rmconf, ctx)
-	struct remoteconf *rmconf;
-	void *ctx;
+static cert_t *
+save_certbuf(gen)
+	struct isakmp_gen *gen;
 {
-	struct append_cr_ctx *actx = (struct append_cr_ctx *) ctx;
-	vchar_t *buf, *asn1dn = NULL;
-	int type;
+	cert_t *new;
 
-	/* Do we want to send CR about this? */
-	if (rmconf->send_cr == FALSE)
-		return 0;
-
-	if (rmconf->peerscert != NULL) {
-		type = oakley_get_certtype(rmconf->peerscert);
-		asn1dn = eay_get_x509asn1issuername(rmconf->peerscert);
-	} else if (rmconf->cacert != NULL) {
-		type = oakley_get_certtype(rmconf->cacert);
-		asn1dn = eay_get_x509asn1subjectname(rmconf->cacert);
-	} else
-		return 0;
-
-	if (asn1dn == NULL) {
-		plog(LLV_ERROR, LOCATION, actx->iph1->remote,
-		     "Failed to get CR ASN1 DN from certificate\n");
-		return 0;
+	if(ntohs(gen->len) <= sizeof(*gen)){
+		plog(LLV_ERROR, LOCATION, NULL,
+			 "Len is too small !!.\n");
+		return NULL;
 	}
 
-	buf = vmalloc(1 + asn1dn->l);
-	if (buf == NULL)
-		goto err;
+	new = oakley_newcert();
+	if (!new) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Failed to get CERT buffer.\n");
+		return NULL;
+	}
 
-	buf->v[0] = type;
-	memcpy(&buf->v[1], asn1dn->v, asn1dn->l);
+	new->pl = vmalloc(ntohs(gen->len) - sizeof(*gen));
+	if (new->pl == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Failed to copy CERT from packet.\n");
+		oakley_delcert(new);
+		new = NULL;
+		return NULL;
+	}
+	memcpy(new->pl->v, gen + 1, new->pl->l);
+	new->type = new->pl->v[0] & 0xff;
+	new->cert.v = new->pl->v + 1;
+	new->cert.l = new->pl->l - 1;
 
-	plog(LLV_DEBUG, LOCATION, actx->iph1->remote,
-	     "appending CR: %s\n",
-	     s_isakmp_certtype(buf->v[0]));
-	plogdump(LLV_DEBUG, buf->v, buf->l);
+	return new;
+}
 
-	actx->plist = isakmp_plist_append_full(actx->plist, buf, ISAKMP_NPTYPE_CR, 1);
+static cert_t *
+save_certx509(cert)
+	X509 *cert;
+{
+	cert_t *new;
+        int len;
+        u_char *bp;
 
-err:
-	vfree(asn1dn);
-	return 0;
+	new = oakley_newcert();
+	if (!new) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Failed to get CERT buffer.\n");
+		return NULL;
+	}
+
+        len = i2d_X509(cert, NULL);
+	new->pl = vmalloc(len);
+	if (new->pl == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"Failed to copy CERT from packet.\n");
+		oakley_delcert(new);
+		new = NULL;
+		return NULL;
+	}
+        bp = (u_char *) new->pl->v;
+        len = i2d_X509(cert, &bp);
+	new->type = ISAKMP_CERT_X509SIGN;
+	new->cert.v = new->pl->v;
+	new->cert.l = new->pl->l;
+
+	return new;
 }
 
 /*
- * Append list of acceptable CRs.
- * RFC2048 3.10
+ * get my CR.
+ * NOTE: No Certificate Authority field is included to CR payload at the
+ * moment. Becuase any certificate authority are accepted without any check.
+ * The section 3.10 in RFC2408 says that this field SHOULD not be included,
+ * if there is no specific certificate authority requested.
  */
-struct payload_list *
-oakley_append_cr(plist, iph1)
-	struct payload_list *plist;
+vchar_t *
+oakley_getcr(iph1)
 	struct ph1handle *iph1;
 {
-	struct append_cr_ctx ctx;
-	struct rmconfselector sel;
+	vchar_t *buf;
 
-	ctx.iph1 = iph1;
-	ctx.plist = plist;
-	if (iph1->rmconf == NULL) {
-		rmconf_selector_from_ph1(&sel, iph1);
-		enumrmconf(&sel, oakley_append_rmconf_cr, &ctx);
-	} else {
-		oakley_append_rmconf_cr(iph1->rmconf, &ctx);
+	buf = vmalloc(1);
+	if (buf == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get cr buffer\n");
+		return NULL;
 	}
+	if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) {
+		buf->v[0] = iph1->rmconf->cacerttype;
+		plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n",
+		s_isakmp_certtype(iph1->rmconf->cacerttype));
+	} else {
+		buf->v[0] = iph1->rmconf->certtype;
+		plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
+		s_isakmp_certtype(iph1->rmconf->certtype));
+	}
+	if (buf->l > 1)
+		plogdump(LLV_DEBUG, buf->v, buf->l);
 
-	return ctx.plist;
+	return buf;
 }
 
 /*
@@ -2336,20 +2423,17 @@
 oakley_checkcr(iph1)
 	struct ph1handle *iph1;
 {
-	int type;
-
 	if (iph1->cr_p == NULL)
 		return 0;
 
 	plog(LLV_DEBUG, LOCATION, iph1->remote,
 		"peer transmitted CR: %s\n",
-		s_isakmp_certtype(oakley_get_certtype(iph1->cr_p)));
+		s_isakmp_certtype(iph1->cr_p->type));
 
-	type = oakley_get_certtype(iph1->cr_p);
-	if (type != oakley_get_certtype(iph1->rmconf->mycert)) {
+	if (iph1->cr_p->type != iph1->rmconf->certtype) {
 		plog(LLV_ERROR, LOCATION, iph1->remote,
-		     "such a cert type isn't supported: %d\n",
-		     type);
+			"such a cert type isn't supported: %d\n",
+			(char)iph1->cr_p->type);
 		return -1;
 	}
 
@@ -2398,10 +2482,10 @@
 	int error = -1;
 	
 	/* SKEYID */
-	switch (iph1->approval->authmethod) {
+	switch (AUTHMETHOD(iph1)) {
 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
 #ifdef ENABLE_HYBRID
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
+	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 #endif
 		if (iph1->etype != ISAKMP_ETYPE_IDENT) {
@@ -2664,7 +2748,7 @@
 					iph1->approval->encklen);
 	if (keylen == -1) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"invalid encryption algorithm %d, "
+			"invalid encryption algoritym %d, "
 			"or invalid key length %d.\n",
 			iph1->approval->enctype,
 			iph1->approval->encklen);
@@ -2768,7 +2852,7 @@
 	if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
 	 || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"encryption algorithm %d isn't supported.\n",
+			"encryption algoritym %d isn't supported.\n",
 			iph1->approval->enctype);
 		goto end;
 	}
@@ -2788,6 +2872,36 @@
 	return error;
 }
 
+/* allocated new buffer for CERT */
+cert_t *
+oakley_newcert()
+{
+	cert_t *new;
+
+	new = racoon_calloc(1, sizeof(*new));
+	if (new == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get cert's buffer\n");
+		return NULL;
+	}
+
+	new->pl = NULL;
+
+	return new;
+}
+
+/* delete buffer for CERT */
+void
+oakley_delcert(cert)
+	cert_t *cert;
+{
+	if (!cert)
+		return;
+	if (cert->pl)
+		VPTRINIT(cert->pl);
+	racoon_free(cert);
+}
+
 /*
  * compute IV and set to ph1handle
  *	IV = hash(g^xi | g^xr)
@@ -2842,7 +2956,7 @@
 	newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
 	if (newivm->iv->l == -1) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"invalid encryption algorithm %d.\n",
+			"invalid encryption algoriym %d.\n",
 			iph1->approval->enctype);
 		vfree(buf);
 		oakley_delivm(newivm);
@@ -2924,7 +3038,7 @@
 	newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
 	if (newivm->iv->l == -1) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"invalid encryption algorithm %d.\n",
+			"invalid encryption algoriym %d.\n",
 			iph1->approval->enctype);
 		goto end;
 	}
@@ -2988,7 +3102,7 @@
 	blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
 	if (blen == -1) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"invalid encryption algorithm %d.\n",
+			"invalid encryption algoriym %d.\n",
 			iph1->approval->enctype);
 		goto end;
 	}
@@ -3110,7 +3224,7 @@
 	blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
 	if (blen == -1) {
 		plog(LLV_ERROR, LOCATION, NULL,
-			"invalid encryption algorithm %d.\n",
+			"invalid encryption algoriym %d.\n",
 			iph1->approval->enctype);
 		goto end;
 	}
diff --git a/src/racoon/oakley.h b/src/racoon/oakley.h
index f8cdb76..a8dbbd2 100644
--- a/src/racoon/oakley.h
+++ b/src/racoon/oakley.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: oakley.h,v 1.7 2009/03/12 10:57:26 tteras Exp $	*/
+/*	$NetBSD: oakley.h,v 1.5 2006/10/06 12:02:27 manu Exp $	*/
 
 /* Id: oakley.h,v 1.13 2005/05/30 20:12:43 fredsen Exp */
 
@@ -89,18 +89,21 @@
 #define OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R	65010
 #endif
 
-/*
- * The following are valid when the Vendor ID is one of
- * the following:
- *
- *	MD5("A GSS-API Authentication Method for IKE")
- *	MD5("GSSAPI") (recognized by Windows 2000)
- *	MD5("MS NT5 ISAKMPOAKLEY") (sent by Windows 2000)
- */
+					/*	65500 -> still private
+					 * to avoid clash with GSSAPI_KRB below 
+					 */
+#define FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I	65500
 
-#define OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB	(65001 + 0x10000)
-#define OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB_REAL	65001
 
+	/*
+	 * The following are valid when the Vendor ID is one of
+	 * the following:
+	 *
+	 *	MD5("A GSS-API Authentication Method for IKE")
+	 *	MD5("GSSAPI") (recognized by Windows 2000)
+	 *	MD5("MS NT5 ISAKMPOAKLEY") (sent by Windows 2000)
+	 */
+#define   OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB	65001
 #define OAKLEY_ATTR_GRP_DESC		4 /* B */
 #define   OAKLEY_ATTR_GRP_DESC_MODP768		1
 #define   OAKLEY_ATTR_GRP_DESC_MODP1024		2
@@ -160,6 +163,13 @@
 	vchar_t *order;
 };
 
+/* certificate holder */
+typedef struct cert_t_tag {
+	u_int8_t type;		/* type of CERT, must be same to pl->v[0]*/
+	vchar_t cert;		/* pointer to the CERT */
+	vchar_t *pl;		/* CERT payload minus isakmp general header */
+} cert_t;
+
 struct ph1handle;
 struct ph2handle;
 struct isakmp_ivm;
@@ -190,13 +200,10 @@
 extern vchar_t *oakley_ph1hash_base_i __P((struct ph1handle *, int));
 extern vchar_t *oakley_ph1hash_base_r __P((struct ph1handle *, int));
 
-extern int oakley_get_certtype __P((vchar_t *));
 extern int oakley_validate_auth __P((struct ph1handle *));
 extern int oakley_getmycert __P((struct ph1handle *));
 extern int oakley_getsign __P((struct ph1handle *));
 extern vchar_t *oakley_getcr __P((struct ph1handle *));
-extern struct payload_list *oakley_append_cr __P((struct payload_list *,
-						  struct ph1handle *));
 extern int oakley_checkcr __P((struct ph1handle *));
 extern int oakley_needcr __P((int));
 struct isakmp_gen;
@@ -207,6 +214,8 @@
 extern int oakley_skeyid_dae __P((struct ph1handle *));
 
 extern int oakley_compute_enckey __P((struct ph1handle *));
+extern cert_t *oakley_newcert __P((void));
+extern void oakley_delcert __P((cert_t *));
 extern int oakley_newiv __P((struct ph1handle *));
 extern struct isakmp_ivm *oakley_newiv2 __P((struct ph1handle *, u_int32_t));
 extern void oakley_delivm __P((struct isakmp_ivm *));
@@ -215,4 +224,20 @@
 extern vchar_t *oakley_do_encrypt __P((struct ph1handle *,
 	vchar_t *, vchar_t *, vchar_t *));
 
+#ifdef ENABLE_HYBRID
+#define AUTHMETHOD(iph1)						     \
+    (((iph1)->rmconf->xauth &&						     \
+    (iph1)->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ? \
+	FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I : (iph1)->approval->authmethod)
+#define RMAUTHMETHOD(iph1)						     \
+    (((iph1)->rmconf->xauth &&						     \
+    (iph1)->rmconf->proposal->authmethod ==                                  \
+	OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I) ?                             \
+	FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I :                                  \
+	(iph1)->rmconf->proposal->authmethod)
+#else
+#define AUTHMETHOD(iph1) (iph1)->approval->authmethod
+#define RMAUTHMETHOD(iph1) (iph1)->rmconf->proposal->authmethod
+#endif /* ENABLE_HYBRID */
+
 #endif /* _OAKLEY_H */
diff --git a/src/racoon/pfkey.c b/src/racoon/pfkey.c
index e69cb94..e73acc8 100644
--- a/src/racoon/pfkey.c
+++ b/src/racoon/pfkey.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: pfkey.c,v 1.57 2011/03/15 13:20:14 vanhu Exp $	*/
+/*	$NetBSD: pfkey.c,v 1.18.4.5 2008/03/05 22:14:24 mgrooms Exp $	*/
 
-/* $Id: pfkey.c,v 1.57 2011/03/15 13:20:14 vanhu Exp $ */
+/* $Id: pfkey.c,v 1.18.4.5 2008/03/05 22:14:24 mgrooms Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -77,7 +77,6 @@
 #include "vmbuf.h"
 #include "plog.h"
 #include "sockmisc.h"
-#include "session.h"
 #include "debug.h"
 
 #include "schedule.h"
@@ -95,7 +94,6 @@
 #include "algorithm.h"
 #include "sainfo.h"
 #include "admin.h"
-#include "evt.h"
 #include "privsep.h"
 #include "strnames.h"
 #include "backupsa.h"
@@ -131,9 +129,6 @@
 static int pk_recvspdget __P((caddr_t *));
 static int pk_recvspddump __P((caddr_t *));
 static int pk_recvspdflush __P((caddr_t *));
-#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
-static int pk_recvmigrate __P((caddr_t *));
-#endif
 static struct sadb_msg *pk_recv __P((int, int *));
 
 static int (*pkrecvf[]) __P((caddr_t *)) = {
@@ -161,21 +156,17 @@
 pk_recvspdexpire,
 NULL,	/* SADB_X_SPDDELETE2 */
 NULL,	/* SADB_X_NAT_T_NEW_MAPPING */
-#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
-pk_recvmigrate,
-#else
 NULL,	/* SADB_X_MIGRATE */
-#endif
 #if (SADB_MAX > 24)
 #error "SADB extra message?"
 #endif
 };
 
-static int addnewsp __P((caddr_t *, struct sockaddr *, struct sockaddr *));
+static int addnewsp __P((caddr_t *));
 
 /* cope with old kame headers - ugly */
 #ifndef SADB_X_AALG_MD5
-#define SADB_X_AALG_MD5		SADB_AALG_MD5
+#define SADB_X_AALG_MD5		SADB_AALG_MD5	
 #endif
 #ifndef SADB_X_AALG_SHA
 #define SADB_X_AALG_SHA		SADB_AALG_SHA
@@ -201,10 +192,8 @@
  *	0: success
  *	-1: fail
  */
-static int
-pfkey_handler(ctx, fd)
-	void *ctx;
-	int fd;
+int
+pfkey_handler()
 {
 	struct sadb_msg *msg;
 	int len;
@@ -213,16 +202,9 @@
 
 	/* receive pfkey message. */
 	len = 0;
-	msg = (struct sadb_msg *) pk_recv(fd, &len);
+	msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len);
 	if (msg == NULL) {
 		if (len < 0) {
-		        /* do not report EAGAIN as error; well get
-		         * called from main loop later. and it's normal
-		         * when spd dump is received during reload and
-		         * this function is called in loop. */
-		        if (errno == EAGAIN)
-		                goto end;
-
 			plog(LLV_ERROR, LOCATION, NULL,
 				"failed to recv from pfkey (%s)\n",
 				strerror(errno));
@@ -233,7 +215,7 @@
 		}
 	}
 
-	plog(LLV_DEBUG, LOCATION, NULL, "got pfkey %s message\n",
+	plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
 		s_pfkey_type(msg->sadb_msg_type));
 	plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
 
@@ -289,7 +271,7 @@
 	if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
 		goto end;
 
-	error = 1;
+	error = 0;
 end:
 	if (msg)
 		racoon_free(msg);
@@ -303,32 +285,20 @@
 pfkey_dump_sadb(satype)
 	int satype;
 {
-	int s;
+	int s = -1;
 	vchar_t *buf = NULL;
 	pid_t pid = getpid();
 	struct sadb_msg *msg = NULL;
 	size_t bl, ml;
 	int len;
-	int bufsiz;
 
-	if ((s = privsep_socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
+	if ((s = privsep_pfkey_open()) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"libipsec failed pfkey open: %s\n",
 			ipsec_strerror());
 		return NULL;
 	}
 
-	if ((bufsiz = pfkey_set_buffer_size(s, lcconf->pfkey_buffer_size)) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "libipsec failed pfkey set buffer size to %d: %s\n",
-		     lcconf->pfkey_buffer_size, ipsec_strerror());
-		return NULL;
-	} else if (bufsiz < lcconf->pfkey_buffer_size) {
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "pfkey socket receive buffer set to %dKB, instead of %d\n",
-		     bufsiz, lcconf->pfkey_buffer_size);
-	}
-
 	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
 	if (pfkey_send_dump(s, satype) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -355,7 +325,7 @@
 			 "type %i, pid %i\n", msg->sadb_msg_type, msg->sadb_msg_pid);
 		    continue;
 		}
-
+		
 
 		ml = msg->sadb_msg_len << 3;
 		bl = buf ? buf->l : 0;
@@ -379,7 +349,8 @@
 done:
 	if (msg)
 		racoon_free(msg);
-	close(s);
+	if (s >= 0)
+		privsep_pfkey_close(s);
 	return buf;
 }
 
@@ -429,25 +400,12 @@
 pfkey_init()
 {
 	int i, reg_fail;
-	int bufsiz;
 
-	if ((lcconf->sock_pfkey = pfkey_open()) < 0) {
+	if ((lcconf->sock_pfkey = privsep_pfkey_open()) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"libipsec failed pfkey open (%s)\n", ipsec_strerror());
 		return -1;
 	}
-	if ((bufsiz = pfkey_set_buffer_size(lcconf->sock_pfkey,
-					    lcconf->pfkey_buffer_size)) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "libipsec failed to set pfkey buffer size to %d (%s)\n",
-		     lcconf->pfkey_buffer_size, ipsec_strerror());
-		return -1;
-	} else if (bufsiz < lcconf->pfkey_buffer_size) {
-		plog(LLV_WARNING, LOCATION, NULL,
-		     "pfkey socket receive buffer set to %dKB, instead of %d\n",
-		     bufsiz, lcconf->pfkey_buffer_size);
-	}
-
 	if (fcntl(lcconf->sock_pfkey, F_SETFL, O_NONBLOCK) == -1)
 		plog(LLV_WARNING, LOCATION, NULL,
 		    "failed to set the pfkey socket to NONBLOCK\n");
@@ -489,25 +447,6 @@
 		return -1;
 	}
 #endif
-	monitor_fd(lcconf->sock_pfkey, pfkey_handler, NULL, 0);
-	return 0;
-}
-
-int
-pfkey_reload()
-{
-	flushsp();
-
-	if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-			"libipsec sending spddump failed: %s\n",
-			ipsec_strerror());
-		return -1;
-	}
-
-	while (pfkey_handler(NULL, lcconf->sock_pfkey) > 0)
-		continue;
-
 	return 0;
 }
 
@@ -778,29 +717,6 @@
 	return res;
 }
 
-void
-pk_fixup_sa_addresses(mhp)
-	caddr_t *mhp;
-{
-	struct sockaddr *src, *dst;
-
-	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
-	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
-	set_port(src, PORT_ISAKMP);
-	set_port(dst, PORT_ISAKMP);
-
-#ifdef ENABLE_NATT
-	if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
-		/* NAT-T is enabled for this SADB entry; copy
-		 * the ports from NAT-T extensions */
-		if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
-			set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
-		if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
-			set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
-	}
-#endif
-}
-
 int
 pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
 		e_type, e_keylen, a_type, a_keylen, flags)
@@ -841,7 +757,7 @@
 			goto bad;
 		*a_keylen >>= 3;
 
-		if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
+		if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5 
 		 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
 			/* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
 			*a_type = SADB_X_AALG_MD5;
@@ -882,6 +798,35 @@
 	return -1;
 }
 
+/* called from scheduler */
+void
+pfkey_timeover_stub(p)
+	void *p;
+{
+
+	pfkey_timeover((struct ph2handle *)p);
+}
+
+void
+pfkey_timeover(iph2)
+	struct ph2handle *iph2;
+{
+	plog(LLV_ERROR, LOCATION, NULL,
+		"%s give up to get IPsec-SA due to time up to wait.\n",
+		saddrwop2str(iph2->dst));
+	SCHED_KILL(iph2->sce);
+
+	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
+	if (iph2->side == INITIATOR)
+		pk_sendeacquire(iph2);
+
+	unbindph12(iph2);
+	remph2(iph2);
+	delph2(iph2);
+
+	return;
+}
+
 /*%%%*/
 /* send getspi message per ipsec protocol per remote address */
 /*
@@ -898,28 +843,25 @@
 	struct saprop *pp;
 	struct saproto *pr;
 	u_int32_t minspi, maxspi;
-	u_int8_t natt_type = 0;
-	u_int16_t sport = 0, dport = 0;
+	int proxy = 0;
 
-	if (iph2->side == INITIATOR)
+	if (iph2->side == INITIATOR) {
 		pp = iph2->proposal;
-	else
-		pp = iph2->approval;
-
-	if (iph2->sa_src && iph2->sa_dst) {
-		/* MIPv6: Use SA addresses, not IKE ones */
-		src = dupsaddr(iph2->sa_src);
-		dst = dupsaddr(iph2->sa_dst);
+		proxy = iph2->ph1->rmconf->support_proxy;
 	} else {
-		/* Common case: SA addresses and IKE ones are the same */
-		src = dupsaddr(iph2->src);
-		dst = dupsaddr(iph2->dst);
+		pp = iph2->approval;
+		if (iph2->sainfo && iph2->sainfo->id_i)
+			proxy = 1;
 	}
 
-	if (src == NULL || dst == NULL) {
-		racoon_free(src);
-		racoon_free(dst);
-		return -1;
+	/* for mobile IPv6 */
+	if (proxy && iph2->src_id && iph2->dst_id &&
+	    ipsecdoi_transportmode(pp)) {
+		src = iph2->src_id;
+		dst = iph2->dst_id;
+	} else {
+		src = iph2->src;
+		dst = iph2->dst;
 	}
 
 	for (pr = pp->head; pr != NULL; pr = pr->next) {
@@ -929,8 +871,6 @@
 		if (satype == ~0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"invalid proto_id %d\n", pr->proto_id);
-			racoon_free(src);
-			racoon_free(dst);
 			return -1;
 		}
 		/* this works around a bug in Linux kernel where it allocates 4 byte
@@ -947,36 +887,30 @@
 		if (mode == ~0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"invalid encmode %d\n", pr->encmode);
-			racoon_free(src);
-			racoon_free(dst);
 			return -1;
 		}
 
 #ifdef ENABLE_NATT
-		if (pr->udp_encap) {
-			natt_type = iph2->ph1->natt_options->encaps_type;
-			sport=extract_port(src);
-			dport=extract_port(dst);
+		/* XXX should we do a copy of src/dst for each pr ?
+		 */
+		if (! pr->udp_encap) {
+			/* Remove port information, that SA doesn't use it */
+			set_port(src, 0);
+			set_port(dst, 0);
 		}
 #endif
-
 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
-		if (pfkey_send_getspi_nat(
+		if (pfkey_send_getspi(
 				lcconf->sock_pfkey,
 				satype,
 				mode,
 				dst,			/* src of SA */
 				src,			/* dst of SA */
-				natt_type,
-				dport,
-				sport,
 				minspi, maxspi,
 				pr->reqid_in, iph2->seq) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"ipseclib failed send getspi (%s)\n",
 				ipsec_strerror());
-			racoon_free(src);
-			racoon_free(dst);
 			return -1;
 		}
 		plog(LLV_DEBUG, LOCATION, NULL,
@@ -984,8 +918,6 @@
 			sadbsecas2str(dst, src, satype, 0, mode));
 	}
 
-	racoon_free(src);
-	racoon_free(dst);
 	return 0;
 }
 
@@ -993,13 +925,13 @@
  * receive GETSPI from kernel.
  */
 static int
-pk_recvgetspi(mhp)
+pk_recvgetspi(mhp) 
 	caddr_t *mhp;
 {
 	struct sadb_msg *msg;
 	struct sadb_sa *sa;
 	struct ph2handle *iph2;
-	struct sockaddr *src, *dst;
+	struct sockaddr *dst;
 	int proto_id;
 	int allspiok, notfound;
 	struct saprop *pp;
@@ -1007,17 +939,14 @@
 
 	/* validity check */
 	if (mhp[SADB_EXT_SA] == NULL
-	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
-	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL) {
+	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"inappropriate sadb getspi message passed.\n");
 		return -1;
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
-	pk_fixup_sa_addresses(mhp);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
-	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
 	/* the message has to be processed or not ? */
 	if (msg->sadb_msg_pid != getpid()) {
@@ -1057,7 +986,7 @@
 			notfound = 0;
 			plog(LLV_DEBUG, LOCATION, NULL,
 				"pfkey GETSPI succeeded: %s\n",
-				sadbsecas2str(dst, src,
+				sadbsecas2str(iph2->dst, iph2->src,
 				    msg->sadb_msg_satype,
 				    sa->sadb_sa_spi,
 				    ipsecdoi2pfkey_mode(pr->encmode)));
@@ -1069,7 +998,7 @@
 	if (notfound) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"get spi for unknown address %s\n",
-			saddrwop2str(dst));
+			saddrwop2str(iph2->dst));
 		return -1;
 	}
 
@@ -1079,6 +1008,7 @@
 		if (isakmp_post_getspi(iph2) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"failed to start post getspi.\n");
+			unbindph12(iph2);
 			remph2(iph2);
 			delph2(iph2);
 			iph2 = NULL;
@@ -1098,38 +1028,34 @@
 {
 	struct saproto *pr;
 	struct pfkey_send_sa_args sa_args;
+	int proxy = 0;
 
 	/* sanity check */
 	if (iph2->approval == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"no approvaled SAs found.\n");
-		return -1;
 	}
 
+	if (iph2->side == INITIATOR)
+		proxy = iph2->ph1->rmconf->support_proxy;
+	else if (iph2->sainfo && iph2->sainfo->id_i)
+		proxy = 1;
+
 	/* fill in some needed for pfkey_send_update2 */
 	memset (&sa_args, 0, sizeof (sa_args));
 	sa_args.so = lcconf->sock_pfkey;
-	if (iph2->lifetime_secs)
-		sa_args.l_addtime = iph2->lifetime_secs;
-	else
-		sa_args.l_addtime = iph2->approval->lifetime;
-	sa_args.seq = iph2->seq;
+	sa_args.l_addtime = iph2->approval->lifetime;
+	sa_args.seq = iph2->seq; 
 	sa_args.wsize = 4;
 
-	if (iph2->sa_src && iph2->sa_dst) {
-		/* MIPv6: Use SA addresses, not IKE ones */
-		sa_args.dst = dupsaddr(iph2->sa_src);
-		sa_args.src = dupsaddr(iph2->sa_dst);
+	/* for mobile IPv6 */
+	if (proxy && iph2->src_id && iph2->dst_id &&
+	    ipsecdoi_transportmode(iph2->approval)) {
+		sa_args.dst = iph2->src_id;
+		sa_args.src = iph2->dst_id;
 	} else {
-		/* Common case: SA addresses and IKE ones are the same */
-		sa_args.dst = dupsaddr(iph2->src);
-		sa_args.src = dupsaddr(iph2->dst);
-	}
-
-	if (sa_args.src == NULL || sa_args.dst == NULL) {
-		racoon_free(sa_args.src);
-		racoon_free(sa_args.dst);
-		return -1;
+		sa_args.dst = iph2->src;
+		sa_args.src = iph2->dst;
 	}
 
 	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
@@ -1138,8 +1064,6 @@
 		if (sa_args.satype == ~0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"invalid proto_id %d\n", pr->proto_id);
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
 			return -1;
 		}
 		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
@@ -1153,8 +1077,6 @@
 		if (sa_args.mode == ~0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"invalid encmode %d\n", pr->encmode);
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
 			return -1;
 		}
 #endif
@@ -1165,12 +1087,9 @@
 				pr->head->trns_id,
 				pr->head->authtype,
 				&sa_args.e_type, &sa_args.e_keylen,
-				&sa_args.a_type, &sa_args.a_keylen,
-				&sa_args.flags) < 0){
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
+				&sa_args.a_type, &sa_args.a_keylen, 
+				&sa_args.flags) < 0)
 			return -1;
-		}
 
 #if 0
 		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
@@ -1190,15 +1109,19 @@
 #ifdef ENABLE_NATT
 		if (pr->udp_encap) {
 			sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
-			sa_args.l_natt_sport = extract_port(iph2->ph1->remote);
-			sa_args.l_natt_dport = extract_port(iph2->ph1->local);
-			sa_args.l_natt_oa = iph2->natoa_src;
+			sa_args.l_natt_sport = extract_port (iph2->ph1->remote);
+			sa_args.l_natt_dport = extract_port (iph2->ph1->local);
+			sa_args.l_natt_oa = NULL;  // FIXME: Here comes OA!!!
 #ifdef SADB_X_EXT_NAT_T_FRAG
 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
 #endif
+		} else {
+			/* Remove port information, that SA doesn't use it */
+			set_port(sa_args.src, 0);
+			set_port(sa_args.dst, 0);
 		}
-#endif
 
+#endif
 		/* more info to fill in */
 		sa_args.spi = pr->spi;
 		sa_args.reqid = pr->reqid_in;
@@ -1209,8 +1132,6 @@
 			plog(LLV_ERROR, LOCATION, NULL,
 				"libipsec failed send update (%s)\n",
 				ipsec_strerror());
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
 			return -1;
 		}
 
@@ -1224,11 +1145,11 @@
 		 * But it is impossible because there is not key in the
 		 * information from the kernel.
 		 */
-
+		
 		/* change some things before backing up */
 		sa_args.wsize = 4;
 		sa_args.l_bytes = iph2->approval->lifebyte * 1024;
-
+		
 		if (backupsa_to_file(&sa_args) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"backuped SA failed: %s\n",
@@ -1242,8 +1163,6 @@
 #endif
 	}
 
-	racoon_free(sa_args.src);
-	racoon_free(sa_args.dst);
 	return 0;
 }
 
@@ -1273,7 +1192,6 @@
 		return -1;
 	}
 	msg = (struct sadb_msg *)mhp[0];
-	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
@@ -1328,14 +1246,14 @@
 			pr->ok = 1;
 			plog(LLV_DEBUG, LOCATION, NULL,
 				"pfkey UPDATE succeeded: %s\n",
-				sadbsecas2str(dst, src,
+				sadbsecas2str(iph2->dst, iph2->src,
 				    msg->sadb_msg_satype,
 				    sa->sadb_sa_spi,
 				    sa_mode));
 
 			plog(LLV_INFO, LOCATION, NULL,
 				"IPsec-SA established: %s\n",
-				sadbsecas2str(dst, src,
+				sadbsecas2str(iph2->dst, iph2->src,
 					msg->sadb_msg_satype, sa->sadb_sa_spi,
 					sa_mode));
 		}
@@ -1348,11 +1266,10 @@
 		return 0;
 
 	/* turn off the timer for calling pfkey_timeover() */
-	sched_cancel(&iph2->sce);
-
+	SCHED_KILL(iph2->sce);
+	
 	/* update status */
 	iph2->status = PHASE2ST_ESTABLISHED;
-	evt_phase2(iph2, EVT_PHASE2_UP, NULL);
 
 #ifdef ENABLE_STATS
 	gettimeofday(&iph2->end, NULL);
@@ -1360,15 +1277,29 @@
 		"phase2", "quick", timedelta(&iph2->start, &iph2->end));
 #endif
 
+	/* count up */
+	iph2->ph1->ph2cnt++;
+
 	/* turn off schedule */
-	sched_cancel(&iph2->scr);
+	SCHED_KILL(iph2->scr);
+
+	/* Force the update of ph2's ports, as there is at least one
+	 * situation where they'll mismatch with ph1's values
+	 */
+
+#ifdef ENABLE_NATT
+	set_port(iph2->src, extract_port(iph2->ph1->local));
+	set_port(iph2->dst, extract_port(iph2->ph1->remote));
+#endif
 
 	/*
 	 * since we are going to reuse the phase2 handler, we need to
 	 * remain it and refresh all the references between ph1 and ph2 to use.
 	 */
-	sched_schedule(&iph2->sce, iph2->approval->lifetime,
-		       isakmp_ph2expire_stub);
+	unbindph12(iph2);
+
+	iph2->sce = sched_new(iph2->approval->lifetime,
+	    isakmp_ph2expire_stub, iph2);
 
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
 	return 0;
@@ -1382,6 +1313,7 @@
 	struct ph2handle *iph2;
 {
 	struct saproto *pr;
+	int proxy = 0;
 	struct pfkey_send_sa_args sa_args;
 
 	/* sanity check */
@@ -1391,30 +1323,26 @@
 		return -1;
 	}
 
+	if (iph2->side == INITIATOR)
+		proxy = iph2->ph1->rmconf->support_proxy;
+	else if (iph2->sainfo && iph2->sainfo->id_i)
+		proxy = 1;
+
 	/* fill in some needed for pfkey_send_update2 */
 	memset (&sa_args, 0, sizeof (sa_args));
 	sa_args.so = lcconf->sock_pfkey;
-	if (iph2->lifetime_secs)
-		sa_args.l_addtime = iph2->lifetime_secs;
-	else
-		sa_args.l_addtime = iph2->approval->lifetime;
+	sa_args.l_addtime = iph2->approval->lifetime;
 	sa_args.seq = iph2->seq;
 	sa_args.wsize = 4;
 
-	if (iph2->sa_src && iph2->sa_dst) {
-		/* MIPv6: Use SA addresses, not IKE ones */
-		sa_args.src = dupsaddr(iph2->sa_src);
-		sa_args.dst = dupsaddr(iph2->sa_dst);
+	/* for mobile IPv6 */
+	if (proxy && iph2->src_id && iph2->dst_id &&
+	    ipsecdoi_transportmode(iph2->approval)) {
+		sa_args.src = iph2->src_id;
+		sa_args.dst = iph2->dst_id;
 	} else {
-		/* Common case: SA addresses and IKE ones are the same */
-		sa_args.src = dupsaddr(iph2->src);
-		sa_args.dst = dupsaddr(iph2->dst);
-	}
-
-	if (sa_args.src == NULL || sa_args.dst == NULL) {
-		racoon_free(sa_args.src);
-		racoon_free(sa_args.dst);
-		return -1;
+		sa_args.src = iph2->src;
+		sa_args.dst = iph2->dst;
 	}
 
 	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
@@ -1423,8 +1351,6 @@
 		if (sa_args.satype == ~0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"invalid proto_id %d\n", pr->proto_id);
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
 			return -1;
 		}
 		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
@@ -1438,8 +1364,6 @@
 		if (sa_args.mode == ~0) {
 			plog(LLV_ERROR, LOCATION, NULL,
 				"invalid encmode %d\n", pr->encmode);
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
 			return -1;
 		}
 #endif
@@ -1451,12 +1375,9 @@
 				pr->head->trns_id,
 				pr->head->authtype,
 				&sa_args.e_type, &sa_args.e_keylen,
-				&sa_args.a_type, &sa_args.a_keylen,
-				&sa_args.flags) < 0){
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
+				&sa_args.a_type, &sa_args.a_keylen, 
+				&sa_args.flags) < 0)
 			return -1;
-		}
 
 #if 0
 		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
@@ -1481,12 +1402,22 @@
 			sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
 			sa_args.l_natt_sport = extract_port(iph2->ph1->local);
 			sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
-			sa_args.l_natt_oa = iph2->natoa_dst;
+			sa_args.l_natt_oa = NULL; // FIXME: Here comes OA!!!
 #ifdef SADB_X_EXT_NAT_T_FRAG
 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
 #endif
+		} else {
+			/* Remove port information, that SA doesn't use it */
+			set_port(sa_args.src, 0);
+			set_port(sa_args.dst, 0);
 		}
+
+#else
+		/* Remove port information, it is not used without NAT-T */
+		set_port(sa_args.src, 0);
+		set_port(sa_args.dst, 0);
 #endif
+
 		/* more info to fill in */
 		sa_args.spi = pr->spi_p;
 		sa_args.reqid = pr->reqid_out;
@@ -1497,8 +1428,6 @@
 			plog(LLV_ERROR, LOCATION, NULL,
 				"libipsec failed send add (%s)\n",
 				ipsec_strerror());
-			racoon_free(sa_args.src);
-			racoon_free(sa_args.dst);
 			return -1;
 		}
 
@@ -1524,8 +1453,6 @@
 			sa_args.satype, sa_args.spi, sa_args.mode));
 #endif
 	}
-	racoon_free(sa_args.src);
-	racoon_free(sa_args.dst);
 	return 0;
 }
 
@@ -1553,7 +1480,6 @@
 		return -1;
 	}
 	msg = (struct sadb_msg *)mhp[0];
-	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
@@ -1588,7 +1514,7 @@
 
 	plog(LLV_INFO, LOCATION, NULL,
 		"IPsec-SA established: %s\n",
-		sadbsecas2str(src, dst,
+		sadbsecas2str(iph2->src, iph2->dst,
 			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
 
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
@@ -1618,7 +1544,6 @@
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
-	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
@@ -1652,63 +1577,54 @@
 			    sa_mode));
 		return 0;
 	}
-
-	/* resent expiry message? */
-	if (iph2->status > PHASE2ST_ESTABLISHED)
-		return 0;
-
-	/* still negotiating? */
-	if (iph2->status < PHASE2ST_ESTABLISHED) {
-		/* not a hard timeout? */
-		if (mhp[SADB_EXT_LIFETIME_HARD] == NULL)
-			return 0;
-
+	if (iph2->status != PHASE2ST_ESTABLISHED) {
 		/*
-		 * We were negotiating for that SA (w/o much success
-		 * from current status) and kernel has decided our time
-		 * is over trying (xfrm_larval_drop controls that and
-		 * is enabled by default on Linux >= 2.6.28 kernels).
+		 * If the status is not equal to PHASE2ST_ESTABLISHED,
+		 * racoon ignores this expire message.  There are two reason.
+		 * One is that the phase 2 probably starts because there is
+		 * a potential that racoon receives the acquire message
+		 * without receiving a expire message.  Another is that racoon
+		 * may receive the multiple expire messages from the kernel.
 		 */
 		plog(LLV_WARNING, LOCATION, NULL,
-		     "PF_KEY EXPIRE message received from kernel for SA"
-		     " being negotiated. Stopping negotiation.\n");
+			"the expire message is received "
+			"but the handler has not been established.\n");
+		return 0;
 	}
 
-	/* turn off the timer for calling isakmp_ph2expire() */
-	sched_cancel(&iph2->sce);
+	/* turn off the timer for calling isakmp_ph2expire() */ 
+	SCHED_KILL(iph2->sce);
 
-	if (iph2->status == PHASE2ST_ESTABLISHED &&
-	    iph2->side == INITIATOR) {
-		struct ph1handle *iph1hint;
-		/*
-		 * Active phase 2 expired and we were initiator.
-		 * Begin new phase 2 exchange, so we can keep on sending
-		 * traffic.
-		 */
+	iph2->status = PHASE2ST_EXPIRED;
+
+	/* INITIATOR, begin phase 2 exchange. */
+	/* allocate buffer for status management of pfkey message */
+	if (iph2->side == INITIATOR) {
+
+		initph2(iph2);
 
 		/* update status for re-use */
-		iph1hint = iph2->ph1;
-		initph2(iph2);
 		iph2->status = PHASE2ST_STATUS2;
 
-		/* start quick exchange */
-		if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) {
+		/* start isakmp initiation by using ident exchange */
+		if (isakmp_post_acquire(iph2) < 0) {
 			plog(LLV_ERROR, LOCATION, iph2->dst,
 				"failed to begin ipsec sa "
 				"re-negotication.\n");
+			unbindph12(iph2);
 			remph2(iph2);
 			delph2(iph2);
 			return -1;
 		}
 
 		return 0;
+		/*NOTREACHED*/
 	}
 
-	/*
-	 * We are responder or the phase 2 was not established.
-	 * Just remove the ph2handle to reflect SADB.
-	 */
-	iph2->status = PHASE2ST_EXPIRED;
+	/* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
+	/* RESPONDER always delete ph2handle, keep silent.  RESPONDER doesn't
+	 * manage IPsec SA, so delete the list */
+	unbindph12(iph2);
 	remph2(iph2);
 	delph2(iph2);
 
@@ -1722,15 +1638,17 @@
 	struct sadb_msg *msg;
 	struct sadb_x_policy *xpl;
 	struct secpolicy *sp_out = NULL, *sp_in = NULL;
-	struct ph2handle *iph2;
-	struct sockaddr *src, *dst;     /* IKE addresses (for exchanges) */
-	struct sockaddr *sp_src, *sp_dst;   /* SP addresses (selectors). */
-	struct sockaddr *sa_src = NULL, *sa_dst = NULL ; /* SA addresses */
+#define MAXNESTEDSA	5	/* XXX */
+	struct ph2handle *iph2[MAXNESTEDSA];
+	struct sockaddr *src, *dst;
+	int n;	/* # of phase 2 handler */
+	int remoteid=0;
 #ifdef HAVE_SECCTX
 	struct sadb_x_sec_ctx *m_sec_ctx;
 #endif /* HAVE_SECCTX */
 	struct policyindex spidx;
 
+
 	/* ignore this message because of local test mode. */
 	if (f_local)
 		return 0;
@@ -1746,11 +1664,8 @@
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
-	/* acquire does not have nat-t ports; so do not bother setting
-	 * the default port 500; just use the port zero for wildcard
-	 * matching the get a valid natted destination */
-	sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
-	sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
 #ifdef HAVE_SECCTX
 	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
@@ -1758,7 +1673,7 @@
 	if (m_sec_ctx != NULL) {
 		plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
 		     m_sec_ctx->sadb_x_ctx_doi);
-		plog(LLV_INFO, LOCATION, NULL,
+		plog(LLV_INFO, LOCATION, NULL, 
 		     "security context algorithm: %u\n",
 		     m_sec_ctx->sadb_x_ctx_alg);
 		plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
@@ -1775,81 +1690,50 @@
 		return 0;
 	}
 
-	/* ignore it if src or dst are multicast addresses. */
-	if ((sp_dst->sa_family == AF_INET
-	  && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_dst)->sin_addr.s_addr)))
+	/* ignore it if src is multicast address */
+    {
+	struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+
+	if ((sa->sa_family == AF_INET
+	  && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
 #ifdef INET6
-	 || (sp_dst->sa_family == AF_INET6
-	  && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_dst)->sin6_addr))
+	 || (sa->sa_family == AF_INET6
+	  && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
 #endif
 	) {
 		plog(LLV_DEBUG, LOCATION, NULL,
-			"ignore due to multicast destination address: %s.\n",
-			saddrwop2str(sp_dst));
+			"ignore due to multicast address: %s.\n",
+			saddrwop2str(sa));
 		return 0;
 	}
+    }
+   	
+    	/* ignore, if we do not listen on source address */
+	{
+		/* reasons behind:
+		 * - if we'll contact peer from address we do not listen -
+		 *   we will be unable to complete negotiation;
+		 * - if we'll negotiate using address we're listening -
+		 *   remote peer will send packets to address different
+		 *   than one in the policy, so kernel will drop them;
+		 * => therefore this acquire is not for us! --Aidas
+		 */
+		struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+		struct myaddrs *p;
+		int do_listen = 0;
+		for (p = lcconf->myaddrs; p; p = p->next) {
+			if (!cmpsaddrwop(p->addr, sa)) {
+				do_listen = 1;
+				break;
+			}
+		}
 
-	if ((sp_src->sa_family == AF_INET
-	  && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_src)->sin_addr.s_addr)))
-#ifdef INET6
-	 || (sp_src->sa_family == AF_INET6
-	  && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_src)->sin6_addr))
-#endif
-	) {
-		plog(LLV_DEBUG, LOCATION, NULL,
-			"ignore due to multicast source address: %s.\n",
-			saddrwop2str(sp_src));
-		return 0;
-	}
-
-	/* search for proper policyindex */
-	sp_out = getspbyspid(xpl->sadb_x_policy_id);
-	if (sp_out == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
-			xpl->sadb_x_policy_id);
-		return -1;
-	}
-	plog(LLV_DEBUG, LOCATION, NULL,
-		"suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
-
-	/* Before going further, let first get the source and destination
-	 * address that would be used for IKE negotiation. The logic is:
-	 * - if SP from SPD image contains local and remote hints, we
-	 *   use them (provided by MIGRATE).
-	 * - otherwise, we use the ones from the ipsecrequest, which means:
-	 *   - the addresses from the request for transport mode
-	 *   - the endpoints addresses for tunnel mode
-	 *
-	 * Note that:
-	 * 1) racoon does not support negotiation of bundles which
-	 *    simplifies the lookup for the addresses in the ipsecrequest
-	 *    list, as we expect only one.
-	 * 2) We do source and destination parts all together and do not
-	 *    accept semi-defined information. This is just a decision,
-	 *    there might be needs.
-	 *
-	 * --arno
-	 */
-	if (sp_out->req && sp_out->req->saidx.mode == IPSEC_MODE_TUNNEL) {
-		/* For Tunnel mode, SA addresses are the endpoints */
-		src = (struct sockaddr *) &sp_out->req->saidx.src;
-		dst = (struct sockaddr *) &sp_out->req->saidx.dst;
-	} else {
-		/* Otherwise use requested addresses.
-		 *
-		 * We need to explicitly setup sa_src and sa_dst too,
-		 * since the SA ports are different from IKE port. And
-		 * src/dst ports will be overwritten when the matching
-		 * phase1 is found. */
-		src = sa_src = sp_src;
-		dst = sa_dst = sp_dst;
-	}
-	if (sp_out->local && sp_out->remote) {
-		/* hints available, let's use them */
-		sa_src = src;
-		sa_dst = dst;
-		src = (struct sockaddr *) sp_out->local;
-		dst = (struct sockaddr *) sp_out->remote;
+		if (!do_listen) {
+			plog(LLV_DEBUG, LOCATION, NULL,
+				"ignore because do not listen on source address : %s.\n",
+				saddrwop2str(sa));
+			return 0;
+		}
 	}
 
 	/*
@@ -1862,25 +1746,27 @@
 	 *       has to prcesss such a acquire message because racoon may
 	 *       lost the expire message.
 	 */
-	iph2 = getph2byid(src, dst, xpl->sadb_x_policy_id);
-	if (iph2 != NULL) {
-		if (iph2->status < PHASE2ST_ESTABLISHED) {
+	iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id);
+	if (iph2[0] != NULL) {
+		if (iph2[0]->status < PHASE2ST_ESTABLISHED) {
 			plog(LLV_DEBUG, LOCATION, NULL,
 				"ignore the acquire because ph2 found\n");
 			return -1;
 		}
-		if (iph2->status == PHASE2ST_EXPIRED)
-			iph2 = NULL;
+		if (iph2[0]->status == PHASE2ST_EXPIRED)
+			iph2[0] = NULL;
 		/*FALLTHROUGH*/
 	}
 
-	/* Check we are listening on source address. If not, ignore. */
-	if (myaddr_getsport(src) == -1) {
-		plog(LLV_DEBUG, LOCATION, NULL,
-		     "Not listening on source address %s. Ignoring ACQUIRE.\n",
-		     saddrwop2str(src));
-		return 0;
+	/* search for proper policyindex */
+	sp_out = getspbyspid(xpl->sadb_x_policy_id);
+	if (sp_out == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
+			xpl->sadb_x_policy_id);
+		return -1;
 	}
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
 
 	/* get inbound policy */
     {
@@ -1916,67 +1802,119 @@
 	}
     }
 
+	memset(iph2, 0, MAXNESTEDSA);
+
+	n = 0;
+
 	/* allocate a phase 2 */
-	iph2 = newph2();
-	if (iph2 == NULL) {
+	iph2[n] = newph2();
+	if (iph2[n] == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to allocate phase2 entry.\n");
 		return -1;
 	}
-	iph2->side = INITIATOR;
-	iph2->spid = xpl->sadb_x_policy_id;
-	iph2->satype = msg->sadb_msg_satype;
-	iph2->seq = msg->sadb_msg_seq;
-	iph2->status = PHASE2ST_STATUS2;
+	iph2[n]->side = INITIATOR;
+	iph2[n]->spid = xpl->sadb_x_policy_id;
+	iph2[n]->satype = msg->sadb_msg_satype;
+	iph2[n]->seq = msg->sadb_msg_seq;
+	iph2[n]->status = PHASE2ST_STATUS2;
 
-	/* set address used by IKE for the negotiation (might differ from
-	 * SA address, i.e. might not be tunnel endpoints or addresses
-	 * of transport mode SA) */
-	iph2->dst = dupsaddr(dst);
-	if (iph2->dst == NULL) {
-		delph2(iph2);
+	/* set end addresses of SA */
+	iph2[n]->dst = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
+	if (iph2[n]->dst == NULL) {
+		delph2(iph2[n]);
 		return -1;
 	}
-	iph2->src = dupsaddr(src);
-	if (iph2->src == NULL) {
-		delph2(iph2);
+	iph2[n]->src = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
+	if (iph2[n]->src == NULL) {
+		delph2(iph2[n]);
 		return -1;
 	}
 
-	/* If sa_src and sa_dst have been set, this mean we have to
-	 * set iph2->sa_src and iph2->sa_dst to provide the addresses
-	 * of the SA because iph2->src and iph2->dst are only the ones
-	 * used for the IKE exchanges. Those that need these addresses
-	 * are for instance pk_sendupdate() or pk_sendgetspi() */
-	if (sa_src) {
-		iph2->sa_src = dupsaddr(sa_src);
-		iph2->sa_dst = dupsaddr(sa_dst);
-	}
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"new acquire %s\n", spidx2str(&sp_out->spidx));
 
-	if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) {
-		delph2(iph2);
+	/* get sainfo */
+    {
+	vchar_t *idsrc, *iddst;
+
+	idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src,
+				sp_out->spidx.prefs, sp_out->spidx.ul_proto);
+	if (idsrc == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get ID for %s\n",
+			spidx2str(&sp_out->spidx));
+		delph2(iph2[n]);
 		return -1;
 	}
+	iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst,
+				sp_out->spidx.prefd, sp_out->spidx.ul_proto);
+	if (iddst == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get ID for %s\n",
+			spidx2str(&sp_out->spidx));
+		vfree(idsrc);
+		delph2(iph2[n]);
+		return -1;
+	}
+	{
+		struct remoteconf *conf;
+		conf = getrmconf(iph2[n]->dst);
+		if (conf != NULL)
+			remoteid=conf->ph1id;
+		else{
+			plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n");
+			remoteid=0;
+		}
+	}
+	iph2[n]->sainfo = getsainfo(idsrc, iddst, NULL, remoteid);
+	vfree(idsrc);
+	vfree(iddst);
+	if (iph2[n]->sainfo == NULL) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to get sainfo.\n");
+		delph2(iph2[n]);
+		return -1;
+		/* XXX should use the algorithm list from register message */
+	}
 
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"selected sainfo: %s\n", sainfo2str(iph2[n]->sainfo));
+    }
+
+	if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) {
+		plog(LLV_ERROR, LOCATION, NULL,
+			"failed to create saprop.\n");
+		delph2(iph2[n]);
+		return -1;
+	}
 #ifdef HAVE_SECCTX
 	if (m_sec_ctx) {
-		set_secctx_in_proposal(iph2, spidx);
+		set_secctx_in_proposal(iph2[n], spidx);
 	}
 #endif /* HAVE_SECCTX */
 
-	insph2(iph2);
+	insph2(iph2[n]);
 
 	/* start isakmp initiation by using ident exchange */
 	/* XXX should be looped if there are multiple phase 2 handler. */
-	if (isakmp_post_acquire(iph2, NULL, TRUE) < 0) {
+	if (isakmp_post_acquire(iph2[n]) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"failed to begin ipsec sa negotication.\n");
-		remph2(iph2);
-		delph2(iph2);
-		return -1;
+		goto err;
 	}
 
 	return 0;
+
+err:
+	while (n >= 0) {
+		unbindph12(iph2[n]);
+		remph2(iph2[n]);
+		delph2(iph2[n]);
+		iph2[n] = NULL;
+		n--;
+	}
+	return -1;
 }
 
 static int
@@ -2004,7 +1942,6 @@
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
-	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
@@ -2036,13 +1973,14 @@
 
 	plog(LLV_ERROR, LOCATION, NULL,
 		"pfkey DELETE received: %s\n",
-		sadbsecas2str(src, dst,
+		sadbsecas2str(iph2->src, iph2->dst,
 			msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
 
 	/* send delete information */
 	if (iph2->status == PHASE2ST_ESTABLISHED)
 		isakmp_info_send_d2(iph2);
 
+	unbindph12(iph2);
 	remph2(iph2);
 	delph2(iph2);
 
@@ -2076,7 +2014,6 @@
 	struct ph2handle *iph2;
 {
 	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
-	struct sockaddr *src = NULL, *dst = NULL;
 	struct sadb_x_policy *xpl;
 	struct sadb_x_ipsecrequest *xisr;
 	struct saproto *pr;
@@ -2095,19 +2032,11 @@
 	/* get policy buffer size */
 	policylen = sizeof(struct sadb_x_policy);
 	if (type != SADB_X_SPDDELETE) {
-		if (iph2->sa_src && iph2->sa_dst) {
-			src = iph2->sa_src; /* MIPv6: Use SA addresses, */
-			dst = iph2->sa_dst; /* not IKE ones             */
-		} else {
-			src = iph2->src; /* Common case: SA addresses */
-			dst = iph2->dst; /* and IKE ones are the same */
-		}
-
 		for (pr = iph2->approval->head; pr; pr = pr->next) {
 			xisrlen = sizeof(*xisr);
 			if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
-				xisrlen += (sysdep_sa_len(src) +
-					    sysdep_sa_len(dst));
+				xisrlen += (sysdep_sa_len(iph2->src)
+				          + sysdep_sa_len(iph2->dst));
 			}
 
 			policylen += PFKEY_ALIGN8(xisrlen);
@@ -2153,7 +2082,7 @@
 		p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
 		p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
 		p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
-
+ 
 		memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
 		len += ctxlen;
 	}
@@ -2192,7 +2121,7 @@
 			goto err;
 		}
 
-		/*
+		/* 
 		 * the policy level cannot be unique because the policy
 		 * is defined later than SA, so req_id cannot be bound to SA.
 		 */
@@ -2212,20 +2141,20 @@
 		if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
 			int src_len, dst_len;
 
-			src_len = sysdep_sa_len(src);
-			dst_len = sysdep_sa_len(dst);
+			src_len = sysdep_sa_len(iph2->src);
+			dst_len = sysdep_sa_len(iph2->dst);
 			xisrlen += src_len + dst_len;
 
-			memcpy(p, src, src_len);
+			memcpy(p, iph2->src, src_len);
 			p += src_len;
 
-			memcpy(p, dst, dst_len);
+			memcpy(p, iph2->dst, dst_len);
 			p += dst_len;
 		}
 
 		xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
 		xisr = (struct sadb_x_ipsecrequest *)p;
-
+		
 	}
 	racoon_free(pr_rlist);
 
@@ -2290,12 +2219,10 @@
 {
 	struct sadb_address *saddr, *daddr;
 	struct sadb_x_policy *xpl;
-	struct sadb_lifetime *lt;
+ 	struct sadb_lifetime *lt;
 	struct policyindex spidx;
 	struct secpolicy *sp;
-	struct sockaddr *local=NULL, *remote=NULL;
-	u_int64_t created;
-	int ret;
+ 	u_int64_t created;
 
 	/* sanity check */
 	if (mhp[0] == NULL
@@ -2350,29 +2277,15 @@
 
 	sp = getsp(&spidx);
 	if (sp == NULL) {
-		plog(LLV_DEBUG, LOCATION, NULL,
-			"this policy did not exist for removal: \"%s\"\n",
+		plog(LLV_ERROR, LOCATION, NULL,
+			"such policy does not already exist: \"%s\"\n",
 			spidx2str(&spidx));
 	} else {
-		/* preserve hints before deleting the SP */
-		local = sp->local;
-		remote = sp->remote;
-		sp->local = NULL;
-		sp->remote = NULL;
-
 		remsp(sp);
 		delsp(sp);
 	}
 
-	/* Add new SP (with old hints) */
-	ret = addnewsp(mhp, local, remote);
-
-	if (local != NULL)
-		racoon_free(local);
-	if (remote != NULL)
-		racoon_free(remote);
-
-	if (ret < 0)
+	if (addnewsp(mhp) < 0)
 		return -1;
 
 	return 0;
@@ -2431,9 +2344,7 @@
 	struct sadb_lifetime *lt;
 	struct policyindex spidx;
 	struct secpolicy *sp;
-	struct sockaddr *local = NULL, *remote = NULL;
 	u_int64_t created;
-	int ret;
 
 	/* sanity check */
 	if (mhp[0] == NULL
@@ -2492,26 +2403,11 @@
 			"such policy already exists. "
 			"anyway replace it: %s\n",
 			spidx2str(&spidx));
-
-		/* preserve hints before deleting the SP */
-		local = sp->local;
-		remote = sp->remote;
-		sp->local = NULL;
-		sp->remote = NULL;
-
 		remsp(sp);
 		delsp(sp);
 	}
 
-	/* Add new SP (with old hints) */
-	ret = addnewsp(mhp, local, remote);
-
-	if (local != NULL)
-		racoon_free(local);
-	if (remote != NULL)
-		racoon_free(remote);
-
-	if (ret < 0)
+	if (addnewsp(mhp) < 0)
 		return -1;
 
 	return 0;
@@ -2732,9 +2628,7 @@
 	struct sadb_lifetime *lt;
 	struct policyindex spidx;
 	struct secpolicy *sp;
-	struct sockaddr *local=NULL, *remote=NULL;
 	u_int64_t created;
-	int ret;
 
 	/* sanity check */
 	if (mhp[0] == NULL) {
@@ -2743,6 +2637,7 @@
 		return -1;
 	}
 	msg = (struct sadb_msg *)mhp[0];
+
 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
@@ -2797,26 +2692,11 @@
 			"such policy already exists. "
 			"anyway replace it: %s\n",
 			spidx2str(&spidx));
-
-		/* preserve hints before deleting the SP */
-		local = sp->local;
-		remote = sp->remote;
-		sp->local = NULL;
-		sp->remote = NULL;
-
 		remsp(sp);
 		delsp(sp);
 	}
 
-	/* Add new SP (with old hints) */
-	ret = addnewsp(mhp, local, remote);
-
-	if (local != NULL)
-		racoon_free(local);
-	if (remote != NULL)
-		racoon_free(remote);
-
-	if (ret < 0)
+	if (addnewsp(mhp) < 0)
 		return -1;
 
 	return 0;
@@ -2838,731 +2718,10 @@
 	return 0;
 }
 
-#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
-
-/* MIGRATE support (pk_recvmigrate() is the handler of MIGRATE message).
- *
- * pk_recvmigrate()
- *   1) some preprocessing and checks
- *   2) parsing of sadb_x_kmaddress extension
- *   3) SP lookup using selectors and content of policy extension from MIGRATE
- *   4) resolution of current local and remote IKE addresses
- *   5) Use of addresses to get Phase 1 handler if any
- *   6) Update of IKE addresses in Phase 1 (iph1->local and iph1->remote)
- *   7) Update of IKE addresses in Phase 2 (iph2->src and iph2->dst)
- *   8) Update of IKE addresses in SP (sp->local and sp->remote)
- *   9) Loop on sadb_x_ipsecrequests pairs from MIGRATE
- *      - update of associated ipsecrequests entries in sp->req (should be
- *        only one as racoon does not support bundles), i.e. update of
- *        tunnel endpoints when required.
- *      - If tunnel mode endpoints have been updated, lookup of associated
- *        Phase 2 handle to also update sa_src and sa_dst entries
- *
- * XXX Note that we do not support yet the update of SA addresses for transport
- *     mode, but only the update of SA addresses for tunnel mode (endpoints).
- *     Reasons are:
- *      - there is no initial need for MIPv6
- *      - racoon does not support bundles
- *      - this would imply more work to deal with sainfo update (if feasible).
- */
-
-/* Generic argument structure for migration callbacks */
-struct migrate_args {
-	struct sockaddr *local;
-	struct sockaddr *remote;
-};
-
-/*
- * Update local and remote addresses of given Phase 1. Schedule removal
- * if negotiation was going on and restart a one from updated address.
- *
- * -1 is returned on error. 0 if everything went right.
- */
-static int
-migrate_ph1_ike_addresses(iph1, arg)
-        struct ph1handle *iph1;
-        void *arg;
-{
-	struct migrate_args *ma = (struct migrate_args *) arg;
-	struct remoteconf *rmconf;
-	u_int16_t port;
-
-	/* Already up-to-date? */
-	if (cmpsaddr(iph1->local, ma->local) == CMPSADDR_MATCH &&
-	    cmpsaddr(iph1->remote, ma->remote) == CMPSADDR_MATCH)
-		return 0;
-
-	if (iph1->status < PHASE1ST_ESTABLISHED) {
-		/* Bad luck! We received a MIGRATE *while* negotiating
-		 * Phase 1 (i.e. it was not established yet). If we act as
-		 * initiator we need to restart the negotiation. As
-		 * responder, our best bet is to update our addresses
-		 * and wait for the initiator to do something */
-		plog(LLV_WARNING, LOCATION, NULL, "MIGRATE received *during* "
-		     "Phase 1 negotiation (%s).\n",
-		     saddr2str_fromto("%s => %s", ma->local, ma->remote));
-
-		/* If we are not acting as initiator, let's just leave and
-		 * let the remote peer handle the restart */
-		rmconf = getrmconf(ma->remote, 0);
-		if (rmconf == NULL || !rmconf->passive) {
-			iph1->status = PHASE1ST_EXPIRED;
-			isakmp_ph1delete(iph1);
-
-			/* This is unlikely, but let's just check if a Phase 1
-			 * for the new addresses already exist */
-			if (getph1byaddr(ma->local, ma->remote, 0)) {
-				plog(LLV_WARNING, LOCATION, NULL, "No need "
-				     "to start a new Phase 1 negotiation. One "
-				     "already exists.\n");
-				return 0;
-			}
-
-			plog(LLV_WARNING, LOCATION, NULL, "As initiator, "
-			     "restarting it.\n");
-			 /* Note that the insertion of the new Phase 1 will not
-			  * interfere with the fact we are called from enumph1,
-			  * because it is inserted as first element. --arno */
-			isakmp_ph1begin_i(rmconf, ma->local, ma->remote);
-
-			return 0;
-		}
-	}
-
-	if (iph1->local != NULL) {
-		plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 local "
-		     "address from %s\n",
-		     saddr2str_fromto("%s to %s", iph1->local, ma->local));
-		port = extract_port(iph1->local);
-		racoon_free(iph1->local);
-	} else
-		port = 0;
-
-	iph1->local = dupsaddr(ma->local);
-	if (iph1->local == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
-		     "Phase 1 local address.\n");
-		return -1;
-	}
-	set_port(iph1->local, port);
-
-	if (iph1->remote != NULL) {
-		plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 remote "
-		     "address from %s\n",
-		     saddr2str_fromto("%s to %s", iph1->remote, ma->remote));
-		port = extract_port(iph1->remote);
-		racoon_free(iph1->remote);
-	} else
-		port = 0;
-
-	iph1->remote = dupsaddr(ma->remote);
-	if (iph1->remote == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
-		     "Phase 1 remote address.\n");
-		return -1;
-	}
-	set_port(iph1->remote, port);
-
-	return 0;
-}
-
-/* Update src and dst of all current Phase 2 handles.
- * with provided local and remote addresses.
- * Our intent is NOT to modify IPsec SA endpoints but IKE
- * addresses so we need to take care to separate those if
- * they are different. -1 is returned on error. 0 if everything
- * went right.
- *
- * Note: we do not maintain port information as it is not
- *       expected to be meaningful --arno
- */
-static int
-migrate_ph2_ike_addresses(iph2, arg)
-	struct ph2handle *iph2;
-	void *arg;
-{
-	struct migrate_args *ma = (struct migrate_args *) arg;
-	struct ph1handle *iph1;
-
-	/* If Phase 2 has an associated Phase 1, migrate addresses */
-	if (iph2->ph1)
-		migrate_ph1_ike_addresses(iph2->ph1, arg);
-
-	/* Already up-to-date? */
-	if (cmpsaddr(iph2->src, ma->local) == CMPSADDR_MATCH &&
-	    cmpsaddr(iph2->dst, ma->remote) == CMPSADDR_MATCH)
-		return 0;
-
-	/* save src/dst as sa_src/sa_dst before rewriting */
-	if (iph2->sa_src == NULL && iph2->sa_dst == NULL) {
-		iph2->sa_src = iph2->src;
-		iph2->sa_dst = iph2->dst;
-		iph2->src = NULL;
-		iph2->dst = NULL;
-	}
-
-	if (iph2->src != NULL)
-		racoon_free(iph2->src);
-	iph2->src = dupsaddr(ma->local);
-	if (iph2->src == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unable to allocate Phase 2 src address.\n");
-		return -1;
-	}
-
-	if (iph2->dst != NULL)
-		racoon_free(iph2->dst);
-	iph2->dst = dupsaddr(ma->remote);
-	if (iph2->dst == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unable to allocate Phase 2 dst address.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* Consider existing Phase 2 handles with given spid and update their source
- * and destination addresses for SA. As racoon does not support bundles, if
- * we modify multiple occurrences, this probably imply rekeying has happened.
- *
- * Both addresses passed to the function are expected not to be NULL and of
- * same family. -1 is returned on error. 0 if everything went right.
- *
- * Specific care is needed to support Phase 2 for which negotiation has
- * already started but are which not yet established.
- */
-static int
-migrate_ph2_sa_addresses(iph2, args)
-	struct ph2handle *iph2;
-	void *args;
-{
-	struct migrate_args *ma = (struct migrate_args *) args;
-
-	if (iph2->sa_src != NULL) {
-		racoon_free(iph2->sa_src);
-		iph2->sa_src = NULL;
-	}
-
-	if (iph2->sa_dst != NULL) {
-		racoon_free(iph2->sa_dst);
-		iph2->sa_dst = NULL;
-	}
-
-	iph2->sa_src = dupsaddr(ma->local);
-	if (iph2->sa_src == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unable to allocate Phase 2 sa_src address.\n");
-		return -1;
-	}
-
-	iph2->sa_dst = dupsaddr(ma->remote);
-	if (iph2->sa_dst == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "unable to allocate Phase 2 sa_dst address.\n");
-		return -1;
-	}
-
-	if (iph2->status < PHASE2ST_ESTABLISHED) {
-		struct remoteconf *rmconf;
-		/* We were negotiating for that SA when we received the MIGRATE.
-		 * We cannot simply update the addresses and let the exchange
-		 * go on. We have to restart the whole negotiation if we are
-		 * the initiator. Otherwise (acting as responder), we just need
-		 * to delete our ph2handle and wait for the initiator to start
-		 * a new negotiation. */
-
-		if (iph2->ph1 && iph2->ph1->rmconf)
-			rmconf = iph2->ph1->rmconf;
-		else
-			rmconf = getrmconf(iph2->dst, 0);
-
-		if (rmconf && !rmconf->passive) {
-			struct ph1handle *iph1hint;
-
-			plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
-			     "*during* IPsec SA negotiation. As initiator, "
-			     "restarting it.\n");
-
-			/* Turn off expiration timer ...*/
-			sched_cancel(&iph2->sce);
-			iph2->status = PHASE2ST_EXPIRED;
-
-			/* ... clean Phase 2 handle ... */
-			iph1hint = iph2->ph1;
-			initph2(iph2);
-			iph2->status = PHASE2ST_STATUS2;
-
-			/* and start a new negotiation */
-			if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) {
-				plog(LLV_ERROR, LOCATION, iph2->dst, "failed "
-				     "to begin IPsec SA renegotiation after "
-				     "MIGRATE reception.\n");
-				remph2(iph2);
-				delph2(iph2);
-				return -1;
-			}
-		} else {
-			plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
-			     "*during* IPsec SA negotiation. As responder, let's"
-			     "wait for the initiator to act.\n");
-
-			/* Simply schedule deletion */
-			isakmp_ph2expire(iph2);
-		}
-	}
-
-	return 0;
-}
-
-/* Update SP hints (local and remote addresses) for future IKE
- * negotiations of SA associated with that SP. -1 is returned
- * on error. 0 if everything went right.
- *
- * Note: we do not maintain port information as it is not
- *       expected to be meaningful --arno
- */
-static int
-migrate_sp_ike_addresses(sp, local, remote)
-        struct secpolicy *sp;
-        struct sockaddr *local, *remote;
-{
-	if (sp == NULL || local == NULL || remote == NULL)
-		return -1;
-
-	if (sp->local != NULL)
-		racoon_free(sp->local);
-
-	sp->local = dupsaddr(local);
-	if (sp->local == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
-		     "local hint for SP.\n");
-		return -1;
-	}
-
-	if (sp->remote != NULL)
-		racoon_free(sp->remote);
-
-	sp->remote = dupsaddr(remote);
-	if (sp->remote == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
-		     "remote hint for SP.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* Given current ipsecrequest (isr_cur) to be migrated in considered
-   tree, the function first checks that it matches the expected one
-   (xisr_old) provided in MIGRATE message and then updates the addresses
-   if it is tunnel mode (with content of xisr_new). Various other checks
-   are performed. For transport mode, structures are not modified, only
-   the checks are done. -1 is returned on error. */
-static int
-migrate_ph2_one_isr(spid, isr_cur, xisr_old, xisr_new)
-        u_int32_t spid;
-        struct ipsecrequest *isr_cur;
-	struct sadb_x_ipsecrequest *xisr_old, *xisr_new;
-{
-	struct secasindex *saidx = &isr_cur->saidx;
-	struct sockaddr *osaddr, *odaddr, *nsaddr, *ndaddr;
-	struct ph2selector ph2sel;
-	struct migrate_args ma;
-
-	/* First, check that mode and proto do match */
-	if (xisr_old->sadb_x_ipsecrequest_proto != saidx->proto ||
-	    xisr_old->sadb_x_ipsecrequest_mode != saidx->mode ||
-	    xisr_new->sadb_x_ipsecrequest_proto != saidx->proto ||
-	    xisr_new->sadb_x_ipsecrequest_mode != saidx->mode)
-		return -1;
-
-	/* Then, verify reqid if necessary */
-	if (isr_cur->saidx.reqid &&
-	    (xisr_old->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
-	     xisr_new->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
-	     isr_cur->saidx.reqid != xisr_old->sadb_x_ipsecrequest_reqid ||
-	     isr_cur->saidx.reqid != xisr_new->sadb_x_ipsecrequest_reqid))
-		return -1;
-
-	/* If not tunnel mode, our work is over */
-	if (saidx->mode != IPSEC_MODE_TUNNEL) {
-		plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "non tunnel mode isr, skipping SA address migration.\n");
-		return 0;
-	}
-
-	/* Tunnel mode: let's check addresses do match and then update them. */
-	osaddr = (struct sockaddr *)(xisr_old + 1);
-	odaddr = (struct sockaddr *)(((u_int8_t *)osaddr) + sysdep_sa_len(osaddr));
-	nsaddr = (struct sockaddr *)(xisr_new + 1);
-	ndaddr = (struct sockaddr *)(((u_int8_t *)nsaddr) + sysdep_sa_len(nsaddr));
-
-	/* Check family does match */
-	if (osaddr->sa_family != odaddr->sa_family ||
-	    nsaddr->sa_family != ndaddr->sa_family)
-		return -1;
-
-	/* Check family does match */
-	if (saidx->src.ss_family != osaddr->sa_family)
-		return -1;
-
-	/* We log IPv4 to IPv6 and IPv6 to IPv4 switches */
-	if (nsaddr->sa_family != osaddr->sa_family)
-		plog(LLV_INFO, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "changing address families (%d to %d) for endpoints.\n",
-		     osaddr->sa_family, nsaddr->sa_family);
-
-	if (cmpsaddr(osaddr, (struct sockaddr *) &saidx->src) != CMPSADDR_MATCH ||
-	    cmpsaddr(odaddr, (struct sockaddr *) &saidx->dst) != CMPSADDR_MATCH) {
-		plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "mismatch of addresses in saidx and xisr.\n");
-		return -1;
-	}
-
-	/* Excellent. Let's grab associated Phase 2 handle (if any)
-	 * and update its sa_src and sa_dst entries.  Note that we
-	 * make the assumption that racoon does not support bundles
-	 * and make the lookup using spid: we blindly update
-	 * sa_src and sa_dst for _all_ found Phase 2 handles */
-	memset(&ph2sel, 0, sizeof(ph2sel));
-	ph2sel.spid = spid;
-
-	memset(&ma, 0, sizeof(ma));
-	ma.local = nsaddr;
-	ma.remote = ndaddr;
-
-	if (enumph2(&ph2sel, migrate_ph2_sa_addresses, &ma) < 0)
-		return -1;
-
-	/* Now we can do the update of endpoints in secasindex */
-	memcpy(&saidx->src, nsaddr, sysdep_sa_len(nsaddr));
-	memcpy(&saidx->dst, ndaddr, sysdep_sa_len(ndaddr));
-
-	return 0;
-}
-
-/* Process the raw (unparsed yet) list of sadb_x_ipsecrequests of MIGRATE
- * message. For each sadb_x_ipsecrequest pair (old followed by new),
- * the corresponding ipsecrequest entry in the SP is updated. Associated
- * existing Phase 2 handle is also updated (if any) */
-static int
-migrate_sp_isr_list(sp, xisr_list, xisr_list_len)
-        struct secpolicy *sp;
-	struct sadb_x_ipsecrequest *xisr_list;
-	int xisr_list_len;
-{
-	struct sadb_x_ipsecrequest *xisr_new, *xisr_old = xisr_list;
-	int xisr_old_len, xisr_new_len;
-	struct ipsecrequest *isr_cur;
-
-	isr_cur = sp->req; /* ipsecrequest list from from sp */
-
-	while (xisr_list_len > 0 && isr_cur != NULL) {
-		/* Get old xisr (length field is in bytes) */
-		xisr_old_len = xisr_old->sadb_x_ipsecrequest_len;
-		if (xisr_old_len < sizeof(*xisr_old) ||
-		    xisr_old_len + sizeof(*xisr_new) > xisr_list_len) {
-			plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-			     "invalid ipsecrequest length. Exiting.\n");
-			return -1;
-		}
-
-		/* Get new xisr with updated info */
-		xisr_new = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_old) + xisr_old_len);
-		xisr_new_len = xisr_new->sadb_x_ipsecrequest_len;
-		if (xisr_new_len < sizeof(*xisr_new) ||
-		    xisr_new_len + xisr_old_len > xisr_list_len) {
-			plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-			     "invalid ipsecrequest length. Exiting.\n");
-			return -1;
-		}
-
-		/* Start by migrating current ipsecrequest from SP */
-		if (migrate_ph2_one_isr(sp->id, isr_cur, xisr_old, xisr_new) == -1) {
-			plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-			     "Unable to match and migrate isr. Exiting.\n");
-			return -1;
-		}
-
-		/* Update pointers for next round */
-		xisr_list_len -= xisr_old_len + xisr_new_len;
-		xisr_old = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_new) +
-							  xisr_new_len);
-
-		isr_cur = isr_cur->next; /* Get next ipsecrequest from SP */
-	}
-
-	/* Check we had the same amount of pairs in the MIGRATE
-	   as the number of ipsecrequests in the SP */
-	if ((xisr_list_len != 0) || isr_cur != NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "number of ipsecrequest does not match the one in SP.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* Parse sadb_x_kmaddress extension and make local and remote
- * parameters point to the new addresses (zero copy). -1 is
- * returned on error, meaning that addresses are not usable */
-static int
-parse_kmaddress(kmaddr, local, remote)
-        struct sadb_x_kmaddress *kmaddr;
-	struct sockaddr **local, **remote;
-{
-	int addrslen, local_len=0;
-	struct ph1handle *iph1;
-
-	if (kmaddr == NULL)
-		return -1;
-
-	/* Grab addresses in sadb_x_kmaddress extension */
-	addrslen = PFKEY_EXTLEN(kmaddr) - sizeof(*kmaddr);
-	if (addrslen < sizeof(struct sockaddr))
-		return -1;
-
-	*local = (struct sockaddr *)(kmaddr + 1);
-
-	switch ((*local)->sa_family) {
-	case AF_INET:
-		local_len = sizeof(struct sockaddr_in);
-		break;
-#ifdef INET6
-	case AF_INET6:
-		local_len = sizeof(struct sockaddr_in6);
-		break;
-#endif
-	default:
-		return -1;
-	}
-
-	if (addrslen != PFKEY_ALIGN8(2*local_len))
-		return -1;
-
-	*remote = (struct sockaddr *)(((u_int8_t *)(*local)) + local_len);
-
-	if ((*local)->sa_family != (*remote)->sa_family)
-		return -1;
-
-	return 0;
-}
-
-/* Handler of PF_KEY MIGRATE message. Helpers are above */
-static int
-pk_recvmigrate(mhp)
-	caddr_t *mhp;
-{
-	struct sadb_address *saddr, *daddr;
-	struct sockaddr *old_saddr, *new_saddr;
-	struct sockaddr *old_daddr, *new_daddr;
-	struct sockaddr *old_local, *old_remote;
-	struct sockaddr *local, *remote;
-	struct sadb_x_kmaddress *kmaddr;
-	struct sadb_x_policy *xpl;
-	struct sadb_x_ipsecrequest *xisr_list;
-	struct sadb_lifetime *lt;
-	struct policyindex spidx;
-	struct secpolicy *sp;
-	struct ipsecrequest *isr_cur;
-	struct secasindex *oldsaidx;
-	struct ph2handle *iph2;
-	struct ph1handle *iph1;
-	struct ph2selector ph2sel;
-	struct ph1selector ph1sel;
-	u_int32_t spid;
-	u_int64_t created;
-	int xisr_list_len;
-	int ulproto;
-	struct migrate_args ma;
-
-	/* Some sanity checks */
-
-	if (mhp[0] == NULL
-	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
-	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
-	 || mhp[SADB_X_EXT_KMADDRESS] == NULL
-	 || mhp[SADB_X_EXT_POLICY] == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-			"SADB_X_MIGRATE: invalid MIGRATE message received.\n");
-		return -1;
-	}
-	kmaddr = (struct sadb_x_kmaddress *)mhp[SADB_X_EXT_KMADDRESS];
-	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
-	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
-	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
-	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
-	if (lt != NULL)
-		created = lt->sadb_lifetime_addtime;
-	else
-		created = 0;
-
-	if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
-		plog(LLV_WARNING, LOCATION, NULL,"SADB_X_MIGRATE: "
-		     "found non IPsec policy in MIGRATE message. Exiting.\n");
-		return -1;
-	}
-
-	if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
-		plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "invalid size for sadb_x_policy. Exiting.\n");
-		return -1;
-	}
-
-	/* Some logging to help debbugging */
-	if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
-		plog(LLV_DEBUG, LOCATION, NULL,
-		     "SADB_X_MIGRATE: Outbound SA being migrated.\n");
-	else
-		plog(LLV_DEBUG, LOCATION, NULL,
-		     "SADB_X_MIGRATE: Inbound SA being migrated.\n");
-
-	/* validity check */
-	xisr_list = (struct sadb_x_ipsecrequest *)(xpl + 1);
-	xisr_list_len = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
-	if (xisr_list_len < sizeof(*xisr_list)) {
-		plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "invalid sadb_x_policy message length. Exiting.\n");
-		return -1;
-	}
-
-	if (parse_kmaddress(kmaddr, &local, &remote) == -1) {
-		plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
-		     "invalid sadb_x_kmaddress extension. Exiting.\n");
-		return -1;
-	}
-
-	/* 0 means ANY */
-	if (saddr->sadb_address_proto == 0)
-		ulproto = IPSEC_ULPROTO_ANY;
-	else
-		ulproto = saddr->sadb_address_proto;
-
-#ifdef HAVE_PFKEY_POLICY_PRIORITY
-	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
-			saddr + 1,
-			daddr + 1,
-			saddr->sadb_address_prefixlen,
-			daddr->sadb_address_prefixlen,
-			ulproto,
-			xpl->sadb_x_policy_priority,
-			created,
-			&spidx);
-#else
-	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
-			saddr + 1,
-			daddr + 1,
-			saddr->sadb_address_prefixlen,
-			daddr->sadb_address_prefixlen,
-			ulproto,
-			created,
-			&spidx);
-#endif
-
-	/* Everything seems ok, let's get the SP.
-	 *
-	 * XXX We could also do the lookup using the spid from xpl.
-	 *     I don't know which one is better.  --arno */
-	sp = getsp(&spidx);
-	if (sp == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL,
-			"SADB_X_MIGRATE: Passed policy does not exist: %s\n",
-			spidx2str(&spidx));
-		return -1;
-	}
-
-	/* Get the best source and destination addresses used for IKE
-	 * negotiation, to find and migrate existing Phase 1 */
-	if (sp->local && sp->remote) {
-		/* hints available, let's use them */
-		old_local  = (struct sockaddr *)sp->local;
-		old_remote = (struct sockaddr *)sp->remote;
-	} else if (sp->req && sp->req->saidx.mode == IPSEC_MODE_TUNNEL) {
-		/* Tunnel mode and no hint, use endpoints */
-		old_local  = (struct sockaddr *)&sp->req->saidx.src;
-		old_remote = (struct sockaddr *)&sp->req->saidx.dst;
-	} else {
-		/* default, use selectors as fallback */
-		old_local  = (struct sockaddr *)&sp->spidx.src;
-		old_remote = (struct sockaddr *)&sp->spidx.dst;
-	}
-
-	/* We migrate all Phase 1 that match our old local and remote
-	 * addresses (no matter their state).
-	 *
-	 * XXX In fact, we should probably havea special treatment for
-	 * Phase 1 that are being established when we receive a MIGRATE.
-	 * This can happen if a movement occurs during the initial IKE
-	 * negotiation. In that case, I wonder if should restart the
-	 * negotiation from the new address or just update things like
-	 * we do it now.
-	 *
-	 * XXX while looking at getph1byaddr(), the comment at the
-	 * beginning of the function expects comparison to happen
-	 * without ports considerations but it uses CMPSADDR() which
-	 * relies either on cmpsaddrstrict() or cmpsaddrwop() based
-	 * on NAT-T support being activated. That make me wonder if I
-	 * should force ports to 0 (ANY) in local and remote values
-	 * used below.
-	 *
-	 * -- arno */
-
-	/* Apply callback data ...*/
-	memset(&ma, 0, sizeof(ma));
-	ma.local = local;
-	ma.remote = remote;
-
-	/* Fill phase1 match criteria ... */
-	memset(&ph1sel, 0, sizeof(ph1sel));
-	ph1sel.local = old_local;
-	ph1sel.remote = old_remote;
-
-
-	/* Have matching Phase 1 found and addresses updated. As this is a
-	 * time consuming task on a busy responder, and MIGRATE messages
-	 * are always sent for *both* inbound and outbound (and possibly
-	 * forward), we only do that for outbound SP. */
-	if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND &&
-	    enumph1(&ph1sel, migrate_ph1_ike_addresses, &ma) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
-		     "to migrate Phase 1 addresses.\n");
-		return -1;
-	}
-
-	/* We can now update IKE addresses in Phase 2 handle. */
-	memset(&ph2sel, 0, sizeof(ph2sel));
-	ph2sel.spid = sp->id;
-	if (enumph2(&ph2sel, migrate_ph2_ike_addresses, &ma) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
-		     "to migrate Phase 2 IKE addresses.\n");
-		return -1;
-	}
-
-	/* and _then_ in SP. */
-	if (migrate_sp_ike_addresses(sp, local, remote) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "SADB_X_MIGRATE: Unable to migrate SP IKE addresses.\n");
-		return -1;
-	}
-
-	/* Loop on sadb_x_ipsecrequest list to possibly update sp->req
-	 * entries and associated live Phase 2 handles (their sa_src
-	 * and sa_dst) */
-	if (migrate_sp_isr_list(sp, xisr_list, xisr_list_len) < 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
-		     "SADB_X_MIGRATE: Unable to migrate isr list.\n");
-		return -1;
-	}
-
-	return 0;
-}
-#endif
-
 #ifndef ANDROID_PATCHED
 
 /*
- * send error against acquire message to kernel.
+ * send error against acquire message to kenrel.
  */
 int
 pk_sendeacquire(iph2)
@@ -3600,8 +2759,8 @@
 #else
 
 int pk_sendeacquire(struct ph2handle *iph2)
-{       
-        exit(1);
+{
+	exit(1);
 }
 
 #endif
@@ -3628,8 +2787,8 @@
 		break;
 	case IPSECDOI_PROTO_IPCOMP:
 		plog(LLV_DEBUG, LOCATION, NULL,
-			"no check of compression algorithm; "
-			"not supported in sadb message.\n");
+			"compression algorithm can not be checked "
+			"because sadb message doesn't support it.\n");
 		return 0;
 	default:
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -3689,11 +2848,6 @@
 		return NULL;
 
 	reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
-	if (reallen < sizeof(buf)) {
-		*lenp = -1;
-		errno = EIO;
-		return NULL;    /*fatal*/
-	}
 	if ((newmsg = racoon_calloc(1, reallen)) == NULL)
 		return NULL;
 
@@ -3726,9 +2880,8 @@
 }
 
 static int
-addnewsp(mhp, local, remote)
+addnewsp(mhp)
 	caddr_t *mhp;
-	struct sockaddr *local, *remote;
 {
 	struct secpolicy *new = NULL;
 	struct sadb_address *saddr, *daddr;
@@ -3937,12 +3090,6 @@
 	}
 #endif /* HAVE_SECCTX */
 
-	/* Set local and remote hints for that SP, if available */
-	if (local && remote) {
-		new->local = dupsaddr(local);
-		new->remote = dupsaddr(remote);
-	}
-
 	inssp(new);
 
 	return 0;
diff --git a/src/racoon/pfkey.h b/src/racoon/pfkey.h
index cfe111d..547f94a 100644
--- a/src/racoon/pfkey.h
+++ b/src/racoon/pfkey.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey.h,v 1.8 2009/07/03 06:40:10 tteras Exp $	*/
+/*	$NetBSD: pfkey.h,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: pfkey.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */
 
@@ -42,17 +42,16 @@
 extern const struct pfkey_satype pfkey_satypes[];
 extern const int pfkey_nsatypes;
 
+extern int pfkey_handler __P((void));
 extern vchar_t *pfkey_dump_sadb __P((int));
 extern void pfkey_flush_sadb __P((u_int));
 extern int pfkey_init __P((void));
-extern int pfkey_reload __P((void));
 
 extern struct pfkey_st *pfkey_getpst __P((caddr_t *, int, int));
 
 extern int pk_checkalg __P((int, int, int));
 
 struct ph2handle;
-extern void pk_fixup_sa_addresses __P((caddr_t *mhp));
 extern int pk_sendgetspi __P((struct ph2handle *));
 extern int pk_sendupdate __P((struct ph2handle *));
 extern int pk_sendadd __P((struct ph2handle *));
@@ -61,6 +60,9 @@
 extern int pk_sendspdadd2 __P((struct ph2handle *));
 extern int pk_sendspddelete __P((struct ph2handle *));
 
+extern void pfkey_timeover_stub __P((void *));
+extern void pfkey_timeover __P((struct ph2handle *));
+
 extern u_int pfkey2ipsecdoi_proto __P((u_int));
 extern u_int ipsecdoi2pfkey_proto __P((u_int));
 extern u_int pfkey2ipsecdoi_mode __P((u_int));
diff --git a/src/racoon/plainrsa-gen.c b/src/racoon/plainrsa-gen.c
index cad1861..1bd5f67 100644
--- a/src/racoon/plainrsa-gen.c
+++ b/src/racoon/plainrsa-gen.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: plainrsa-gen.c,v 1.6 2011/02/11 10:07:19 tteras Exp $	*/
+/*	$NetBSD: plainrsa-gen.c,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: plainrsa-gen.c,v 1.6 2005/04/21 09:08:40 monas Exp */
 /*
@@ -43,13 +43,11 @@
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <unistd.h>
-#include <fcntl.h>
 
 #include <openssl/bio.h>
 #include <openssl/bn.h>
 #include <openssl/err.h>
 #include <openssl/objects.h>
-#include <openssl/pem.h>
 #include <openssl/rsa.h>
 #include <openssl/evp.h>
 #ifdef HAVE_OPENSSL_ENGINE_H
@@ -74,7 +72,6 @@
 	fprintf(stderr, "  -b bits       Generate <bits> long RSA key (default=1024)\n");
 	fprintf(stderr, "  -e pubexp     Public exponent to use (default=0x3)\n");
 	fprintf(stderr, "  -f filename   Filename to store the key to (default=stdout)\n");
-	fprintf(stderr, "  -i filename   Input source for format conversion\n");
 	fprintf(stderr, "  -h            Help\n");
 	fprintf(stderr, "\n");
 	fprintf(stderr, "Report bugs to <ipsec-tools-devel@lists.sourceforge.net>\n");
@@ -85,7 +82,7 @@
  * See RFC 2065, section 3.5 for details about the output format.
  */
 vchar_t *
-mix_b64_pubkey(const RSA *key)
+mix_b64_pubkey(RSA *key)
 {
 	char *binbuf;
 	long binlen, ret;
@@ -119,10 +116,17 @@
 }
 
 int
-print_rsa_key(FILE *fp, const RSA *key)
+gen_rsa_key(FILE *fp, size_t bits, unsigned long exp)
 {
+	RSA *key;
 	vchar_t *pubkey64 = NULL;
 
+	key = RSA_generate_key(bits, exp, NULL, NULL);
+	if (!key) {
+		fprintf(stderr, "RSA_generate_key(): %s\n", eay_strerror());
+		return -1;
+	}
+	
 	pubkey64 = mix_b64_pubkey(key);
 	if (!pubkey64) {
 		fprintf(stderr, "mix_b64_pubkey(): %s\n", eay_strerror());
@@ -131,7 +135,7 @@
 	
 	fprintf(fp, "# : PUB 0s%s\n", pubkey64->v);
 	fprintf(fp, ": RSA\t{\n");
-	fprintf(fp, "\t# RSA %d bits\n", BN_num_bits(key->n));
+	fprintf(fp, "\t# RSA %zu bits\n", bits);
 	fprintf(fp, "\t# pubkey=0s%s\n", pubkey64->v);
 	fprintf(fp, "\tModulus: 0x%s\n", lowercase(BN_bn2hex(key->n)));
 	fprintf(fp, "\tPublicExponent: 0x%s\n", lowercase(BN_bn2hex(key->e)));
@@ -144,92 +148,23 @@
 	fprintf(fp, "  }\n");
 
 	vfree(pubkey64);
+
 	return 0;
 }
 
 int
-print_public_rsa_key(FILE *fp, const RSA *key)
-{
-	vchar_t *pubkey64 = NULL;
-
-	pubkey64 = mix_b64_pubkey(key);
-	if (!pubkey64) {
-		fprintf(stderr, "mix_b64_pubkey(): %s\n", eay_strerror());
-		return -1;
-	}
-	
-	fprintf(fp, ": PUB 0s%s\n", pubkey64->v);
-
-	vfree(pubkey64);
-	return 0;
-}
-
-int
-convert_rsa_key(FILE *fpout, FILE *fpin)
-{
-	int ret;
-	RSA *key = NULL;
-
-	key = PEM_read_RSAPrivateKey(fpin, NULL, NULL, NULL);
-	if (key) {
-		ret = print_rsa_key(fpout, key);
-		RSA_free(key);
-
-		return ret;
-	}
-	
-	rewind(fpin);
-
-	key = PEM_read_RSA_PUBKEY(fpin, NULL, NULL, NULL);
-	if (key) {
-		ret = print_public_rsa_key(fpout, key);
-		RSA_free(key);
-
-		return ret;
-	}
-
-	/* Implement parsing of input stream containing
-	 * private or public "plainrsa" formatted text.
-	 * Convert the result to PEM formatted output.
-	 *
-	 * This seemingly needs manual use of prsaparse().
-	 * An expert ought to do this. */
-
-	fprintf(stderr, "convert_rsa_key: %s\n", "Only conversion from PEM at this time");
-	return -1;
-}
-
-int
-gen_rsa_key(FILE *fp, size_t bits, unsigned long exp)
-{
-	int ret;
-	RSA *key;
-
-	key = RSA_generate_key(bits, exp, NULL, NULL);
-	if (!key) {
-		fprintf(stderr, "RSA_generate_key(): %s\n", eay_strerror());
-		return -1;
-	}
-	
-	ret = print_rsa_key(fp, key);
-	RSA_free(key);
-
-	return ret;
-}
-
-int
 main (int argc, char *argv[])
 {
-	FILE *fp = stdout, *fpin = NULL;
+	FILE *fp = stdout;
 	size_t bits = 1024;
 	unsigned int pubexp = 0x3;
 	struct stat st;
 	extern char *optarg;
 	extern int optind;
-	int c, fd = -1, fdin = -1;
-	char *fname = NULL, *finput = NULL;
+	int c;
+	char *fname = NULL;
 
-	while ((c = getopt(argc, argv, "e:b:f:i:h")) != -1)
+	while ((c = getopt(argc, argv, "e:b:f:h")) != -1)
 		switch (c) {
 			case 'e':
 				if (strncmp(optarg, "0x", 2) == 0)
@@ -243,65 +178,31 @@
 			case 'f':
 				fname = optarg;
 				break;
-			case 'i':
-				finput = optarg;
-				break;
 			case 'h':
 			default:
 				usage(argv[0]);
 		}
 
 	if (fname) {
-		umask(0077);
-		/* Restrictive access due to private key material. */
-		fd = open(fname, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR);
-		if (fd < 0) {
-			if (errno == EEXIST)
-				fprintf(stderr, "%s: file exists! Please use a different name.\n", fname);
-			else
-				fprintf(stderr, "%s: %s\n", fname, strerror(errno));
+		if (stat(fname, &st) >= 0) {
+			fprintf(stderr, "%s: file exists! Please use a different name.\n", fname);
 			exit(1);
 		}
-		fp = fdopen(fd, "w");
+
+		umask(0077);
+		fp = fopen(fname, "w");
 		if (fp == NULL) {
 			fprintf(stderr, "%s: %s\n", fname, strerror(errno));
-			close(fd);
 			exit(1);
 		}
 	}
 
-	if (finput) {
-		/* Restrictive access once more. Do not be fooled by a link. */
-		fdin = open(finput, O_RDONLY | O_NOFOLLOW);
-		if (fdin < 0) {
-			if (errno == ELOOP)
-				fprintf(stderr, "%s: file is a link. Discarded for security.\n", fname);
-			if (fp)
-				fclose(fp);
-			exit(1);
-		}
-		fpin = fdopen(fdin, "r");
-		if (fpin == NULL) {
-			fprintf(stderr, "%s: %s\n", fname, strerror(errno));
-			close(fdin);
-			if (fp)
-				fclose(fp);
-			exit(1);
-		}
-
-	}
-
 	ploginit();
 	eay_init();
 
-	if (fpin)
-		convert_rsa_key(fp, fpin);
-	else
-		gen_rsa_key(fp, bits, pubexp);
+	gen_rsa_key(fp, bits, pubexp);
 
 	fclose(fp);
-	if (fpin)
-		fclose(fpin);
 
 	return 0;
 }
diff --git a/src/racoon/plog.c b/src/racoon/plog.c
index aebfed2..008260d 100644
--- a/src/racoon/plog.c
+++ b/src/racoon/plog.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: plog.c,v 1.7 2011/01/28 12:51:40 tteras Exp $	*/
+/*	$NetBSD: plog.c,v 1.4.6.2 2009/04/20 13:35:36 tteras Exp $	*/
 
 /* Id: plog.c,v 1.11 2006/06/20 09:57:31 vanhu Exp */
 
@@ -36,7 +36,6 @@
 #include <sys/types.h>
 #include <sys/param.h>
 
-#include <arpa/inet.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -79,7 +78,7 @@
 static struct log *logp = NULL;
 static char *logfile = NULL;
 
-static char *plog_common __P((int, const char *, const char *, struct sockaddr *));
+static char *plog_common __P((int, const char *, const char *));
 
 static struct plogtags {
 	char *name;
@@ -95,13 +94,11 @@
 };
 
 static char *
-plog_common(pri, fmt, func, sa)
+plog_common(pri, fmt, func)
 	int pri;
 	const char *fmt, *func;
-	struct sockaddr *sa;
 {
 	static char buf[800];	/* XXX shoule be allocated every time ? */
-	void *addr;
 	char *p;
 	int reslen, len;
 
@@ -119,43 +116,19 @@
 		reslen -= len;
 	}
 
-	if (sa && reslen > 3) {
-		addr = NULL;
-		switch (sa->sa_family) {
-		case AF_INET:
-			addr = &((struct sockaddr_in*)sa)->sin_addr;
-			break;
-		case AF_INET6:
-			addr = &((struct sockaddr_in6*)sa)->sin6_addr;
-			break;
-		}
-		if (inet_ntop(sa->sa_family, addr, p + 1, reslen - 3) != NULL) {
-			*p++ = '[';
-			len = strlen(p);
-			p += len;
-			*p++ = ']';
-			*p++ = ' ';
-			reslen -= len + 3;
-		}
-	}
-
 	if (pri < ARRAYLEN(ptab)) {
 		len = snprintf(p, reslen, "%s: ", ptab[pri].name);
-		p += len;
-		reslen -= len;
+		if (len >= 0 && len < reslen) {
+			p += len;
+			reslen -= len;
+		} else
+			*p = '\0';
 	}
 
 	if (print_location)
-		len = snprintf(p, reslen, "%s: %s", func, fmt);
+		snprintf(p, reslen, "%s: %s", func, fmt);
 	else
-		len = snprintf(p, reslen, "%s", fmt);
-	p += len;
-	reslen -= len;
-
-	/* Force nul termination */
-	if (reslen == 0)
-		p[-1] = 0;
-
+		snprintf(p, reslen, "%s", fmt);
 #ifdef BROKEN_PRINTF
 	while ((p = strstr(buf,"%z")) != NULL)
 		p[1] = 'l';
@@ -184,7 +157,7 @@
 	if (pri > loglevel)
 		return;
 
-	newfmt = plog_common(pri, fmt, func, sa);
+	newfmt = plog_common(pri, fmt, func);
 
 	VA_COPY(ap_bak, ap);
 	
diff --git a/src/racoon/plog.h b/src/racoon/plog.h
index a96b75c..b8cb027 100644
--- a/src/racoon/plog.h
+++ b/src/racoon/plog.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: plog.h,v 1.5 2007/10/02 09:47:40 vanhu Exp $	*/
+/*	$NetBSD: plog.h,v 1.4.6.1 2007/11/06 16:41:27 vanhu Exp $	*/
 
 /* Id: plog.h,v 1.7 2006/06/20 09:57:31 vanhu Exp */
 
@@ -43,7 +43,7 @@
 #define LLV_DEBUG   4
 #define LLV_DEBUG2  5
 
-#define loglevel LLV_INFO
+#define loglevel LLV_DEBUG2
 
 #define plog(level, location, address, ...)                 \
     do {                                                    \
diff --git a/src/racoon/policy.c b/src/racoon/policy.c
index 4c00677..29a6818 100644
--- a/src/racoon/policy.c
+++ b/src/racoon/policy.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: policy.c,v 1.12 2011/03/14 17:18:13 tteras Exp $	*/
+/*	$NetBSD: policy.c,v 1.6.4.1 2007/08/01 11:52:21 vanhu Exp $	*/
 
 /*	$KAME: policy.c,v 1.46 2001/11/16 04:08:10 sakane Exp $	*/
 
@@ -91,17 +91,13 @@
 	struct policyindex *spidx;
 {
 	struct secpolicy *p;
-	struct secpolicy *found = NULL;
 
 	for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) {
-		if (!cmpspidxstrict(spidx, &p->spidx))
+		if (!cmpspidxwild(spidx, &p->spidx))
 			return p;
-
-		if (!found && !cmpspidxwild(spidx, &p->spidx))
-			found = p;
 	}
 
-	return found;
+	return NULL;
 }
 #else
 struct secpolicy *
@@ -141,18 +137,16 @@
 		saddr2str(iph2->src));
 	plog(LLV_DEBUG, LOCATION, NULL, "src2: %s\n",
 		saddr2str((struct sockaddr *)&spidx->src));
-
-	if (cmpsaddr(iph2->src, (struct sockaddr *) &spidx->src) != CMPSADDR_MATCH ||
-	    spidx->prefs != prefixlen)
+	if (cmpsaddrwop(iph2->src, (struct sockaddr *)&spidx->src)
+	 || spidx->prefs != prefixlen)
 		return NULL;
 
 	plog(LLV_DEBUG, LOCATION, NULL, "dst1: %s\n",
 		saddr2str(iph2->dst));
 	plog(LLV_DEBUG, LOCATION, NULL, "dst2: %s\n",
 		saddr2str((struct sockaddr *)&spidx->dst));
-
-	if (cmpsaddr(iph2->dst, (struct sockaddr *) &spidx->dst) != CMPSADDR_MATCH ||
-	    spidx->prefd != prefixlen)
+	if (cmpsaddrwop(iph2->dst, (struct sockaddr *)&spidx->dst)
+	 || spidx->prefd != prefixlen)
 		return NULL;
 
 	plog(LLV_DEBUG, LOCATION, NULL, "looks to be transport mode\n");
@@ -200,11 +194,11 @@
 	 || a->ul_proto != b->ul_proto)
 		return 1;
 
-	if (cmpsaddr((struct sockaddr *) &a->src,
-		     (struct sockaddr *) &b->src) != CMPSADDR_MATCH)
+	if (cmpsaddrstrict((struct sockaddr *)&a->src,
+			   (struct sockaddr *)&b->src))
 		return 1;
-	if (cmpsaddr((struct sockaddr *) &a->dst,
-		     (struct sockaddr *) &b->dst) != CMPSADDR_MATCH)
+	if (cmpsaddrstrict((struct sockaddr *)&a->dst,
+			   (struct sockaddr *)&b->dst))
 		return 1;
 
 #ifdef HAVE_SECCTX
@@ -234,7 +228,8 @@
 	if (!(b->dir == IPSEC_DIR_ANY || a->dir == b->dir))
 		return 1;
 
-	if (!(b->ul_proto == IPSEC_ULPROTO_ANY ||
+	if (!(a->ul_proto == IPSEC_ULPROTO_ANY ||
+	      b->ul_proto == IPSEC_ULPROTO_ANY ||
 	      a->ul_proto == b->ul_proto))
 		return 1;
 
@@ -261,7 +256,7 @@
 		a, b->prefs, saddr2str((struct sockaddr *)&sa1));
 	plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
 		b, b->prefs, saddr2str((struct sockaddr *)&sa2));
-	if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2) > CMPSADDR_WILDPORT_MATCH)
+	if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2))
 		return 1;
 
 #ifndef __linux__
@@ -279,7 +274,7 @@
 		a, b->prefd, saddr2str((struct sockaddr *)&sa1));
 	plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
 		b, b->prefd, saddr2str((struct sockaddr *)&sa2));
-	if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2) > CMPSADDR_WILDPORT_MATCH)
+	if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2))
 		return 1;
 
 #ifdef HAVE_SECCTX
@@ -314,11 +309,6 @@
 		racoon_free(req);
 	}
 	
-	if (sp->local)
-		racoon_free(sp->local);
-	if (sp->remote)
-		racoon_free(sp->remote);
-
 	racoon_free(sp);
 }
 
diff --git a/src/racoon/policy.h b/src/racoon/policy.h
index ef7f923..8c47451 100644
--- a/src/racoon/policy.h
+++ b/src/racoon/policy.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: policy.h,v 1.8 2008/12/05 06:02:20 tteras Exp $	*/
+/*	$NetBSD: policy.h,v 1.5.4.2 2007/06/07 20:34:19 manu Exp $	*/
 
 /* Id: policy.h,v 1.5 2004/06/11 16:00:17 ludvigm Exp */
 
@@ -82,12 +82,6 @@
 	struct ipsecrequest *req;
 				/* pointer to the ipsec request tree, */
 				/* if policy == IPSEC else this value == NULL.*/
-
-	/* MIPv6 needs to perform negotiation of SA using different addresses
-	 * than the endpoints of the SA (CoA for the source). In that case,
-	 * MIGRATE msg provides that info (before movement occurs on the MN) */
-	struct sockaddr *local;
-	struct sockaddr *remote;
 };
 
 /* Security Assocciation Index */
@@ -117,7 +111,7 @@
 #ifdef HAVE_PFKEY_POLICY_PRIORITY
 #define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, _priority, _created, idx)              \
 do {                                                                         \
-	bzero((idx), sizeof(struct policyindex));                            \
+	memset((idx), 0, sizeof(struct policyindex));                        \
 	(idx)->dir = (_dir);                                                 \
 	(idx)->prefs = (ps);                                                 \
 	(idx)->prefd = (pd);                                                 \
@@ -130,7 +124,7 @@
 #else
 #define KEY_SETSECSPIDX(_dir, s, d, ps, pd, ulp, _created, idx)              \
 do {                                                                         \
-	bzero((idx), sizeof(struct policyindex));                            \
+	memset((idx), 0, sizeof(struct policyindex));                        \
 	(idx)->dir = (_dir);                                                 \
 	(idx)->prefs = (ps);                                                 \
 	(idx)->prefd = (pd);                                                 \
diff --git a/src/racoon/privsep.c b/src/racoon/privsep.c
index 55a3908..9e60b89 100644
--- a/src/racoon/privsep.c
+++ b/src/racoon/privsep.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: privsep.c,v 1.21 2011/03/06 08:28:10 tteras Exp $	*/
+/*	$NetBSD: privsep.c,v 1.6 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: privsep.c,v 1.15 2005/08/08 11:23:44 vanhu Exp */
 
@@ -42,17 +42,15 @@
 #include <signal.h>
 #include <pwd.h>
 
-#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/param.h>
 
-#include <netinet/in.h>
-
 #include "gcmalloc.h"
 #include "vmbuf.h"
 #include "misc.h"
 #include "plog.h"
 #include "var.h"
+#include "libpfkey.h"
 
 #include "crypto_openssl.h"
 #include "isakmp_var.h"
@@ -77,28 +75,6 @@
 static int unsafe_env(char *const *);
 static int unknown_name(int);
 static int unsafe_path(char *, int);
-static int rec_fd(int);
-static int send_fd(int, int);
-
-struct socket_args {
-	int domain;
-	int type;
-	int protocol;
-};
-
-struct sockopt_args {
-	int s;
-	int level;
-	int optname;
-	const void *optval;
-	socklen_t optlen;
-};
-
-struct bind_args {
-	int s;
-	const struct sockaddr *addr;
-	socklen_t addrlen;
-};
 
 static int
 privsep_send(sock, buf, len)
@@ -140,19 +116,13 @@
 	    sizeof(com), MSG_PEEK, NULL, NULL)) == -1) {
 		if (errno == EINTR)
 			continue;
-		if (errno == ECONNRESET)
-		    return -1;
 
 		plog(LLV_ERROR, LOCATION, NULL,
 		    "privsep_recv failed: %s\n",
 		    strerror(errno));
 		return -1;
 	}
-
-	/* EOF, other side has closed. */
-	if (len == 0)
-	    return -1;
-
+	
 	/* Check for short packets */
 	if (len < sizeof(com)) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -172,8 +142,6 @@
 	    com.ac_len, 0, NULL, NULL)) == -1) {
 		if (errno == EINTR)
 			continue;
-		if (errno == ECONNRESET)
-		    return -1;
 		plog(LLV_ERROR, LOCATION, NULL,
 		    "failed to recv privsep command: %s\n", 
 		    strerror(errno));
@@ -206,7 +174,7 @@
 	/* 
 	 * When running privsep, certificate and script paths 
 	 * are mandatory, as they enable us to check path safety
-	 * in the privileged instance
+	 * in the privilegied instance
 	 */
 	if ((lcconf->pathinfo[LC_PATHTYPE_CERT] == NULL) ||
 	    (lcconf->pathinfo[LC_PATHTYPE_SCRIPT] == NULL)) {
@@ -215,7 +183,7 @@
 		return -1;
 	}
 
-	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, privsep_sock) != 0) {
+	if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, privsep_sock) != 0) {
 		plog(LLV_ERROR, LOCATION, NULL, 
 		    "Cannot allocate privsep_sock: %s\n", strerror(errno));
 		return -1;
@@ -229,8 +197,6 @@
 		break;
 
 	case 0: /* Child: drop privileges */
-		(void)close(privsep_sock[0]);
-
 		if (lcconf->chroot != NULL) {
 			if (chdir(lcconf->chroot) != 0) {
 				plog(LLV_ERROR, LOCATION, NULL, 
@@ -277,7 +243,7 @@
 		return 0;
 		break;
 
-	default: /* Parent: privileged process */
+	default: /* Parent: privilegied process */
 		break;
 	}
 
@@ -288,6 +254,8 @@
 	for (i = sysconf(_SC_OPEN_MAX); i > 0; i--) {
 		if (i == privsep_sock[0])
 			continue;
+		if (i == privsep_sock[1])
+			continue;
 		if ((f_foreground) && (i == 1))
 			continue;
 		(void)close(i);
@@ -297,20 +265,16 @@
 	ploginit();
 
 	plog(LLV_INFO, LOCATION, NULL, 
-	    "racoon privileged process running with PID %d\n", getpid());
+	    "racoon privilegied process running with PID %d\n", getpid());
 
-	plog(LLV_INFO, LOCATION, NULL,
-	    "racoon unprivileged process running with PID %d\n", child_pid);
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
+#ifdef __NetBSD__
 	setproctitle("[priv]");
 #endif
 	
-	/*
-	 * Don't catch any signal
+	/* 
+	 * Don't catch any signal 
 	 * This duplicate session:signals[], which is static...
 	 */
-	signal(SIGPIPE, SIG_IGN);
 	signal(SIGHUP, SIG_DFL);
 	signal(SIGINT, SIG_DFL);
 	signal(SIGTERM, SIG_DFL);
@@ -367,7 +331,7 @@
 		/* 
 		 * XXX Improvement: instead of returning the key, 
 		 * stuff eay_get_pkcs1privkey and eay_get_x509sign
-		 * together and sign the hash in the privileged 
+		 * together and sign the hash in the privilegied 
 		 * instance? 
 		 * pro: the key remains inaccessible to unpriv
 		 * con: a compromised unpriv racoon can still sign anything
@@ -539,154 +503,6 @@
 			break;
 		}
 
-		case PRIVSEP_SOCKET: {
-			struct socket_args socket_args;
-			int s;
-
-			/* Make sure the string is NULL terminated */
-			if (safety_check(combuf, 0) != 0)
-				break;
-
-			if (combuf->bufs.buflen[0] !=
-			    sizeof(struct socket_args)) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_socket: corrupted message\n");
-				goto out;
-			}
-			memcpy(&socket_args, bufs[0],
-			       sizeof(struct socket_args));
-
-			if (socket_args.domain != PF_INET &&
-			    socket_args.domain != PF_INET6) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_socket: "
-				     "unauthorized domain (%d)\n",
-				     socket_args.domain);
-				goto out;
-			}
-
-			if ((s = socket(socket_args.domain, socket_args.type,
-					socket_args.protocol)) == -1) {
-				reply->hdr.ac_errno = errno;
-				break;
-			}
-
-			if (send_fd(privsep_sock[0], s) < 0) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				     "privsep_socket: send_fd failed\n");
-				close(s);
-				goto out;
-			}
-
-			close(s);
-			break;
-		}
-
-		case PRIVSEP_BIND: {
-			struct bind_args bind_args;
-			int err, port = 0;
-
-			/* Make sure the string is NULL terminated */
-			if (safety_check(combuf, 0) != 0)
-				break;
-
-			if (combuf->bufs.buflen[0] !=
-			    sizeof(struct bind_args)) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_bind: corrupted message\n");
-				goto out;
-			}
-			memcpy(&bind_args, bufs[0], sizeof(struct bind_args));
-
-			if (combuf->bufs.buflen[1] != bind_args.addrlen) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_bind: corrupted message\n");
-				goto out;
-			}
-			bind_args.addr = (const struct sockaddr *)bufs[1];
-
-			if ((bind_args.s = rec_fd(privsep_sock[0])) < 0) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				     "privsep_bind: rec_fd failed\n");
-				goto out;
-			}
-
-			port = extract_port(bind_args.addr);
-			if (port != PORT_ISAKMP && port != PORT_ISAKMP_NATT &&
-			    port != lcconf->port_isakmp &&
-			    port != lcconf->port_isakmp_natt) {
-				plog(LLV_ERROR, LOCATION, NULL,
-				     "privsep_bind: "
-				     "unauthorized port (%d)\n",
-				     port);
-				close(bind_args.s);
-				goto out;
-			}
-
-			err = bind(bind_args.s, bind_args.addr,
-				   bind_args.addrlen);
-
-			if (err)
-				reply->hdr.ac_errno = errno;
-
-			close(bind_args.s);
-			break;
-		}
-
-		case PRIVSEP_SETSOCKOPTS: {
-			struct sockopt_args sockopt_args;
-			int err;
-
-			/* Make sure the string is NULL terminated */
-			if (safety_check(combuf, 0) != 0)
-				break;
-
-			if (combuf->bufs.buflen[0] !=
-			    sizeof(struct sockopt_args)) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_setsockopt: "
-				     "corrupted message\n");
-				goto out;
-			}
-			memcpy(&sockopt_args, bufs[0],
-			       sizeof(struct sockopt_args));
-
-			if (combuf->bufs.buflen[1] != sockopt_args.optlen) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_setsockopt: corrupted message\n");
-				goto out;
-			}
-			sockopt_args.optval = bufs[1];
-
-			if (sockopt_args.optname != 
-			    (sockopt_args.level == 
-			     IPPROTO_IP ? IP_IPSEC_POLICY :
-			     IPV6_IPSEC_POLICY)) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				    "privsep_setsockopt: "
-				     "unauthorized option (%d)\n",
-				     sockopt_args.optname);
-				goto out;
-			}
-
-			if ((sockopt_args.s = rec_fd(privsep_sock[0])) < 0) {
-				plog(LLV_ERROR, LOCATION, NULL, 
-				     "privsep_setsockopt: rec_fd failed\n");
-				goto out;
-			}
-
-			err = setsockopt(sockopt_args.s,
-					 sockopt_args.level,
-					 sockopt_args.optname,
-					 sockopt_args.optval,
-					 sockopt_args.optlen);
-			if (err)
-				reply->hdr.ac_errno = errno;
-
-			close(sockopt_args.s);
-			break;
-		}
-
 #ifdef ENABLE_HYBRID
 		case PRIVSEP_ACCOUNTING_SYSTEM: {
 			int pool_size;
@@ -871,17 +687,14 @@
 
 		/* This frees reply */
 		if (privsep_send(privsep_sock[0], 
-		    reply, reply->hdr.ac_len) != 0) {
-			racoon_free(reply);
+		    reply, reply->hdr.ac_len) != 0)
 			goto out;
-		}
 
 		racoon_free(combuf);
 	}
 
 out:
-	plog(LLV_INFO, LOCATION, NULL, 
-	    "racoon privileged process %d terminated\n", getpid());
+	plog(LLV_INFO, LOCATION, NULL, "privsep exit\n");
 	_exit(0);
 }
 
@@ -932,6 +745,37 @@
 	return NULL;
 }
 
+/*
+ * No prigilege separation trick here, we just open PFKEY before
+ * dropping root privs and we remember it later.
+ */
+static int  pfkey_socket = -1;
+int
+privsep_pfkey_open(void)
+{
+	int ps;
+
+	if (pfkey_socket != -1)
+		return pfkey_socket;
+
+	ps = pfkey_open();
+	if (ps != -1)
+		pfkey_socket = ps;
+
+	return ps;
+}
+
+/*
+ * Consequence of the above trickery: don't 
+ * really close PFKEY as we never re-open it.
+ */
+void
+privsep_pfkey_close(ps)
+	int ps;
+{
+	return;
+}
+
 int
 privsep_script_exec(script, name, envp)
 	char *script;
@@ -1097,224 +941,6 @@
 	return NULL;
 }
 
-/*
- * Create a privileged socket.  On BSD systems a socket obtains special
- * capabilities if it is created by root; setsockopt(IP_IPSEC_POLICY) will
- * succeed but will be ineffective if performed on an unprivileged socket.
- */
-int
-privsep_socket(domain, type, protocol)
-	int domain;
-	int type;
-	int protocol;
-{
-	struct privsep_com_msg *msg;
-	size_t len;
-	char *data;
-	struct socket_args socket_args;
-	int s, saved_errno = 0;
-
-	if (geteuid() == 0)
-		return socket(domain, type, protocol);
-
-	len = sizeof(*msg) + sizeof(socket_args);
-
-	if ((msg = racoon_malloc(len)) == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "Cannot allocate memory: %s\n", strerror(errno));
-		return -1;
-	}
-	bzero(msg, len);
-	msg->hdr.ac_cmd = PRIVSEP_SOCKET;
-	msg->hdr.ac_len = len;
-
-	socket_args.domain = domain;
-	socket_args.type = type;
-	socket_args.protocol = protocol;
-
-	data = (char *)(msg + 1);
-	msg->bufs.buflen[0] = sizeof(socket_args);
-	memcpy(data, &socket_args, msg->bufs.buflen[0]);
-
-	/* frees msg */
-	if (privsep_send(privsep_sock[1], msg, len) != 0)
-		goto out;
-
-	/* Get the privileged socket descriptor from the privileged process. */
-	if ((s = rec_fd(privsep_sock[1])) == -1)
-		return -1;
-
-	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
-		goto out;
-
-	if (msg->hdr.ac_errno != 0) {
-		errno = msg->hdr.ac_errno;
-		goto out;
-	}
-
-	racoon_free(msg);
-	return s;
-
-out:
-	racoon_free(msg);
-	return -1;
-}
-
-/*
- * Bind() a socket to a port.  This works just like regular bind(), except that
- * if you want to bind to the designated isakmp ports and you don't have the
- * privilege to do so, it will ask a privileged process to do it.
- */
-int
-privsep_bind(s, addr, addrlen)
-	int s;
-	const struct sockaddr *addr;
-	socklen_t addrlen;
-{
-	struct privsep_com_msg *msg;
-	size_t len;
-	char *data;
-	struct bind_args bind_args;
-	int err, saved_errno = 0;
-
-	err = bind(s, addr, addrlen);
-	if ((err == 0) || (saved_errno = errno) != EACCES || geteuid() == 0) {
-		if (saved_errno)
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "privsep_bind (%s) = %d\n", strerror(saved_errno), err);
-		errno = saved_errno;
-		return err;
-	}
-
-	len = sizeof(*msg) + sizeof(bind_args) + addrlen;
-
-	if ((msg = racoon_malloc(len)) == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "Cannot allocate memory: %s\n", strerror(errno));
-		return -1;
-	}
-	bzero(msg, len);
-	msg->hdr.ac_cmd = PRIVSEP_BIND;
-	msg->hdr.ac_len = len;
-
-	bind_args.s = -1;
-	bind_args.addr = NULL;
-	bind_args.addrlen = addrlen;
-
-	data = (char *)(msg + 1);
-	msg->bufs.buflen[0] = sizeof(bind_args);
-	memcpy(data, &bind_args, msg->bufs.buflen[0]);
-
-	data += msg->bufs.buflen[0];
-	msg->bufs.buflen[1] = addrlen;
-	memcpy(data, addr, addrlen);
-
-	/* frees msg */
-	if (privsep_send(privsep_sock[1], msg, len) != 0)
-		goto out;
-
-	/* Send the socket descriptor to the privileged process. */
-	if (send_fd(privsep_sock[1], s) < 0)
-		return -1;
-
-	if (privsep_recv(privsep_sock[1], &msg, &len) != 0)
-		goto out;
-
-	if (msg->hdr.ac_errno != 0) {
-		errno = msg->hdr.ac_errno;
-		goto out;
-	}
-
-	racoon_free(msg);
-	return 0;
-
-out:
-	racoon_free(msg);
-	return -1;
-}
-
-/*
- * Set socket options.  This works just like regular setsockopt(), except that
- * if you want to change IP_IPSEC_POLICY or IPV6_IPSEC_POLICY and you don't
- * have the privilege to do so, it will ask a privileged process to do it.
- */
-int
-privsep_setsockopt(s, level, optname, optval, optlen)
-	int s;
-	int level;
-	int optname;
-	const void *optval;
-	socklen_t optlen;
-{
-	struct privsep_com_msg *msg;
-	size_t len;
-	char *data;
-	struct sockopt_args sockopt_args;
-	int err, saved_errno = 0;
-
-	if ((err = setsockopt(s, level, optname, optval, optlen) == 0) || 
-	    (saved_errno = errno) != EACCES ||
-	    geteuid() == 0) {
-		if (saved_errno)
-			plog(LLV_ERROR, LOCATION, NULL,
-			     "privsep_setsockopt (%s)\n",
-			     strerror(saved_errno));
-
-		errno = saved_errno;
-		return err;
-	}
-
-	len = sizeof(*msg) + sizeof(sockopt_args) + optlen;
-
-	if ((msg = racoon_malloc(len)) == NULL) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "Cannot allocate memory: %s\n", strerror(errno));
-		return -1;
-	}
-	bzero(msg, len);
-	msg->hdr.ac_cmd = PRIVSEP_SETSOCKOPTS;
-	msg->hdr.ac_len = len;
-
-	sockopt_args.s = -1;
-	sockopt_args.level = level;
-	sockopt_args.optname = optname;
-	sockopt_args.optval = NULL;
-	sockopt_args.optlen = optlen;
-
-	data = (char *)(msg + 1);
-	msg->bufs.buflen[0] = sizeof(sockopt_args);
-	memcpy(data, &sockopt_args, msg->bufs.buflen[0]);
-
-	data += msg->bufs.buflen[0];
-	msg->bufs.buflen[1] = optlen;
-	memcpy(data, optval, optlen);
-
-	/* frees msg */
-	if (privsep_send(privsep_sock[1], msg, len) != 0)
-		goto out;
-
-	if (send_fd(privsep_sock[1], s) < 0)
-		return -1;
-
-	if (privsep_recv(privsep_sock[1], &msg, &len) != 0) {
-	    plog(LLV_ERROR, LOCATION, NULL,
-		 "privsep_recv failed\n");
-		goto out;
-	}
-
-	if (msg->hdr.ac_errno != 0) {
-		errno = msg->hdr.ac_errno;
-		goto out;
-	}
-
-	racoon_free(msg);
-	return 0;
-
-out:
-	racoon_free(msg);
-	return -1;
-}
-
 #ifdef ENABLE_HYBRID
 int
 privsep_xauth_login_system(usr, pwd)
@@ -1346,7 +972,6 @@
 	msg->bufs.buflen[1] = strlen(pwd) + 1;
 	memcpy(data, pwd, msg->bufs.buflen[1]);
 	
-	/* frees msg */
 	if (privsep_send(privsep_sock[1], msg, len) != 0)
 		return -1;
 
@@ -1409,7 +1034,6 @@
 	data += msg->bufs.buflen[2];
 	memcpy(data, &inout, msg->bufs.buflen[3]);
 
-	/* frees msg */
 	if (privsep_send(privsep_sock[1], msg, len) != 0)
 		return -1;
 
@@ -1465,7 +1089,7 @@
 }
 
 /*
- * Filter unsafe environment variables
+ * Filter unsafe environement variables
  */
 static int
 unsafe_env(envp)
@@ -1486,7 +1110,7 @@
 	return 0;
 found:
 	plog(LLV_ERROR, LOCATION, NULL, 
-	    "privsep_script_exec: unsafe environment variable\n");
+	    "privsep_script_exec: unsafe environement variable\n");
 	return -1;
 }
 
@@ -1537,86 +1161,6 @@
 	return 0;
 }
 
-/* Receive a file descriptor through the argument socket */
-static int
-rec_fd(s)
-	int s;
-{
-	struct msghdr msg;
-	struct cmsghdr *cmsg;
-	int *fdptr;
-	int fd;
-	char cmsbuf[1024];
-	struct iovec iov;
-	char iobuf[1];
-
-	iov.iov_base = iobuf;
-	iov.iov_len = 1;
-
-	if (sizeof(cmsbuf) < CMSG_SPACE(sizeof(fd))) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "send_fd: buffer size too small\n");
-		return -1;
-	}
-	bzero(&msg, sizeof(msg));
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_iov = &iov;
-	msg.msg_iovlen = 1;
-	msg.msg_control = cmsbuf;
-	msg.msg_controllen = CMSG_SPACE(sizeof(fd));
-
-	if (recvmsg(s, &msg, MSG_WAITALL) == -1)
-		return -1;
-
-	cmsg = CMSG_FIRSTHDR(&msg);
-	fdptr = (int *) CMSG_DATA(cmsg);
-	return fdptr[0];
-}
-
-/* Send the file descriptor fd through the argument socket s */
-static int
-send_fd(s, fd)
-	int s;
-	int fd;
-{
-	struct msghdr msg;
-	struct cmsghdr *cmsg;
-	char cmsbuf[1024];
-	struct iovec iov;
-	int *fdptr;
-
-	iov.iov_base = " ";
-	iov.iov_len = 1;
-
-	if (sizeof(cmsbuf) < CMSG_SPACE(sizeof(fd))) {
-		plog(LLV_ERROR, LOCATION, NULL, 
-		    "send_fd: buffer size too small\n");
-		return -1;
-	}
-	bzero(&msg, sizeof(msg));
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_iov = &iov;
-	msg.msg_iovlen = 1;
-	msg.msg_control = cmsbuf;
-	msg.msg_controllen = CMSG_SPACE(sizeof(fd));
-	msg.msg_flags = 0;
-
-	cmsg = CMSG_FIRSTHDR(&msg);
-	cmsg->cmsg_level = SOL_SOCKET;
-	cmsg->cmsg_type = SCM_RIGHTS;
-	cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
-	fdptr = (int *)CMSG_DATA(cmsg);
-	fdptr[0] = fd;
-	msg.msg_controllen = cmsg->cmsg_len;
-
-	if (sendmsg(s, &msg, 0) == -1)
-		return -1;
-
-	return 0;
-}
-
 #ifdef HAVE_LIBPAM
 int 
 privsep_accounting_pam(port, inout)
@@ -1658,7 +1202,6 @@
 	*inout_data = inout;
 	*pool_size_data = isakmp_cfg_config.pool_size;
 
-	/* frees msg */
 	if (privsep_send(privsep_sock[1], msg, len) != 0)
 		return -1;
 
@@ -1729,7 +1272,6 @@
 	data += msg->bufs.buflen[3];
 	memcpy(data, pwd, msg->bufs.buflen[4]);
 
-	/* frees msg */
 	if (privsep_send(privsep_sock[1], msg, len) != 0)
 		return -1;
 
@@ -1782,7 +1324,6 @@
 	data += msg->bufs.buflen[0];
 	memcpy(data, &isakmp_cfg_config.pool_size, msg->bufs.buflen[1]);
 
-	/* frees msg */
 	if (privsep_send(privsep_sock[1], msg, len) != 0)
 		return;
 
diff --git a/src/racoon/privsep.h b/src/racoon/privsep.h
index 732743c..0fa4363 100644
--- a/src/racoon/privsep.h
+++ b/src/racoon/privsep.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: privsep.h,v 1.6 2008/12/08 06:00:54 tteras Exp $	*/
+/*	$NetBSD: privsep.h,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: privsep.h,v 1.5 2005/06/07 12:22:11 fredsen Exp */
 
@@ -42,9 +42,6 @@
 #define PRIVSEP_XAUTH_LOGIN_PAM		0x0807	/* admin_com_bufs follows */
 #define PRIVSEP_CLEANUP_PAM		0x0808	/* admin_com_bufs follows */
 #define PRIVSEP_ACCOUNTING_SYSTEM	0x0809	/* admin_com_bufs follows */
-#define PRIVSEP_SETSOCKOPTS		0x080A	/* admin_com_bufs follows */
-#define PRIVSEP_BIND			0x080B	/* admin_com_bufs follows */
-#define PRIVSEP_SOCKET			0x080C	/* admin_com_bufs follows */
 
 #define PRIVSEP_NBUF_MAX 24
 #define PRIVSEP_BUFLEN_MAX 4096
@@ -61,10 +58,9 @@
 int privsep_init __P((void));
 
 vchar_t *privsep_eay_get_pkcs1privkey __P((char *));
+int privsep_pfkey_open __P((void));
+void privsep_pfkey_close __P((int));
 int privsep_script_exec __P((char *, int, char * const *));
-int privsep_setsockopt __P((int, int, int, const void *, socklen_t));
-int privsep_socket __P((int, int, int));
-int privsep_bind __P((int, const struct sockaddr *, socklen_t));
 vchar_t *privsep_getpsk __P((const char *, const int));
 int privsep_xauth_login_system __P((char *, char *));
 #ifdef HAVE_LIBPAM
diff --git a/src/racoon/proposal.c b/src/racoon/proposal.c
index 33dd311..26c9274 100644
--- a/src/racoon/proposal.c
+++ b/src/racoon/proposal.c
@@ -1,6 +1,6 @@
-/*	$NetBSD: proposal.c,v 1.17 2008/09/19 11:14:49 tteras Exp $	*/
+/*	$NetBSD: proposal.c,v 1.13.4.2 2008/07/22 13:25:42 vanhu Exp $	*/
 
-/* $Id: proposal.c,v 1.17 2008/09/19 11:14:49 tteras Exp $ */
+/* $Id: proposal.c,v 1.13.4.2 2008/07/22 13:25:42 vanhu Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1186,10 +1186,10 @@
 	 * make my proposal according as the client proposal.
 	 * XXX assumed there is only one proposal even if it's the SA bundle.
 	 */
-	for (i = 0; i < MAXPROPPAIRLEN; i++) {
-		if (pair[i] == NULL)
-			continue;
-		
+        for (i = 0; i < MAXPROPPAIRLEN; i++) {
+                if (pair[i] == NULL)
+                        continue;
+
 		if (pp_peer != NULL)
 			flushsaprop(pp_peer);
 
@@ -1226,6 +1226,8 @@
 
 		for (pr = pp_peer->head; pr; pr = pr->next)
 		{
+			struct remoteconf *conf;
+
 			newpr = newsaproto();
 			if (newpr == NULL)
 			{
@@ -1242,7 +1244,9 @@
 			newpr->reqid_in = 0;
 			newpr->reqid_out = 0;
 
-			if (iph2->ph1->rmconf->gen_policy == GENERATE_POLICY_UNIQUE){
+			conf = getrmconf(iph2->dst);
+			if (conf != NULL &&
+				conf->gen_policy == GENERATE_POLICY_UNIQUE){
 				newpr->reqid_in = g_nextreqid ;
 				newpr->reqid_out = g_nextreqid ++;
 				/* 
diff --git a/src/racoon/proposal.h b/src/racoon/proposal.h
index 11fbab8..60fc531 100644
--- a/src/racoon/proposal.h
+++ b/src/racoon/proposal.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: proposal.h,v 1.7 2010/02/09 23:05:16 wiz Exp $	*/
+/*	$NetBSD: proposal.h,v 1.6 2006/12/09 05:52:57 manu Exp $	*/
 
 /* Id: proposal.h,v 1.5 2004/06/11 16:00:17 ludvigm Exp */
 
@@ -88,7 +88,7 @@
 	int reqid_out;			/* request id (outbound) */
 	int reqid_in;			/* request id (inbound) */
 
-	int ok;				/* if 1, success to set SA in kernel */
+	int ok;				/* if 1, success to set SA in kenrel */
 
 	struct satrns *head;		/* header of transform */
 	struct saproto *next;		/* next protocol */
diff --git a/src/racoon/prsa_par.h b/src/racoon/prsa_par.h
index 6e845d8..3bdb11d 100644
--- a/src/racoon/prsa_par.h
+++ b/src/racoon/prsa_par.h
@@ -1,23 +1,24 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
 /* Skeleton interface for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -28,11 +29,10 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -90,27 +90,21 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-
-/* Line 1676 of yacc.c  */
 #line 130 "prsa_par.y"
-
+{
 	BIGNUM *bn;
 	RSA *rsa;
 	char *chr;
 	long num;
 	struct netaddr *naddr;
-
-
-
-/* Line 1676 of yacc.c  */
-#line 108 "prsa_par.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1489 of yacc.c.  */
+#line 103 "prsa_par.h"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE prsalval;
 
-
diff --git a/src/racoon/prsa_par.y b/src/racoon/prsa_par.y
index 1987e4d..f21a82b 100644
--- a/src/racoon/prsa_par.y
+++ b/src/racoon/prsa_par.y
@@ -1,4 +1,4 @@
-/*	$NetBSD: prsa_par.y,v 1.6 2011/03/02 14:49:21 vanhu Exp $	*/
+/*	$NetBSD: prsa_par.y,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: prsa_par.y,v 1.3 2004/11/08 12:04:23 ludvigm Exp */
 
@@ -211,7 +211,6 @@
 			YYABORT;
 		}
 		$$ = base64_pubkey2rsa($2);
-		free($2);
 	}
 	| TAG_PUB HEX
 	{
@@ -237,7 +236,6 @@
 	{
 		int err;
 		struct sockaddr_in *sap;
-		struct addrinfo hints, *res;
 		
 		if ($2 == -1) $2 = 32;
 		if ($2 < 0 || $2 > 32) {
@@ -247,17 +245,12 @@
 		$$ = calloc (sizeof(struct netaddr), 1);
 		$$->prefix = $2;
 		sap = (struct sockaddr_in *)(&$$->sa);
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_INET;
-		hints.ai_flags = AI_NUMERICHOST;
-		err = getaddrinfo($1, NULL, &hints, &res);
-		if (err < 0) {
-			prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err));
+		sap->sin_family = AF_INET;
+		err = inet_pton(AF_INET, $1, (struct in_addr*)(&sap->sin_addr));
+		if (err <= 0) {
+			prsaerror("inet_pton(%s): %s\n", $1, strerror(errno));
 			YYABORT;
 		}
-		memcpy(sap, res->ai_addr, res->ai_addrlen);
-		freeaddrinfo(res);
-		free($1);
 	}
 	;
 
@@ -266,7 +259,6 @@
 	{
 		int err;
 		struct sockaddr_in6 *sap;
-		struct addrinfo hints, *res;
 		
 		if ($2 == -1) $2 = 128;
 		if ($2 < 0 || $2 > 128) {
@@ -276,17 +268,12 @@
 		$$ = calloc (sizeof(struct netaddr), 1);
 		$$->prefix = $2;
 		sap = (struct sockaddr_in6 *)(&$$->sa);
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_INET6;
-		hints.ai_flags = AI_NUMERICHOST;
-		err = getaddrinfo($1, NULL, &hints, &res);
-		if (err < 0) {
-			prsaerror("getaddrinfo(%s): %s\n", $1, gai_strerror(err));
+		sap->sin6_family = AF_INET6;
+		err = inet_pton(AF_INET6, $1, (struct in6_addr*)(&sap->sin6_addr));
+		if (err <= 0) {
+			prsaerror("inet_pton(%s): %s\n", $1, strerror(errno));
 			YYABORT;
 		}
-		memcpy(sap, res->ai_addr, res->ai_addrlen);
-		freeaddrinfo(res);
-		free($1);
 	}
 	;
 
diff --git a/src/racoon/racoon.8 b/src/racoon/racoon.8
index 58fefdd..a6d39d7 100644
--- a/src/racoon/racoon.8
+++ b/src/racoon/racoon.8
@@ -1,4 +1,4 @@
-.\"	$NetBSD: racoon.8,v 1.12 2009/01/24 10:42:31 wiz Exp $
+.\"	$NetBSD: racoon.8,v 1.10 2006/09/09 16:22:10 manu Exp $
 .\"
 .\" Id: racoon.8,v 1.4 2005/04/18 11:07:55 manubsd Exp
 .\"
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 23, 2009
+.Dd November 20, 2000
 .Dt RACOON 8
 .Os
 .\"
@@ -40,7 +40,7 @@
 .Sh SYNOPSIS
 .Nm racoon
 .Bk -words
-.Op Fl 46BdFLVv
+.Op Fl 46BdFLv
 .Ek
 .Bk -words
 .Op Fl f Ar configfile
@@ -115,8 +115,6 @@
 Listen to the ISAKMP key exchange on port
 .Ar isakmp-port
 instead of the default port number, 500.
-.It Fl V
-Print racoon version and compilation options and exit.
 .It Fl v
 This flag causes the packet dump be more verbose, with higher
 debugging level.
diff --git a/src/racoon/racoon.conf.5 b/src/racoon/racoon.conf.5
index 70c7eda..9ddee80 100644
--- a/src/racoon/racoon.conf.5
+++ b/src/racoon/racoon.conf.5
@@ -1,4 +1,4 @@
-.\"	$NetBSD: racoon.conf.5,v 1.61 2010/06/22 20:51:04 wiz Exp $
+.\"	$NetBSD: racoon.conf.5,v 1.34.4.3 2007/09/03 18:07:29 mgrooms Exp $
 .\"
 .\"	Id: racoon.conf.5,v 1.54 2006/08/22 18:17:17 manubsd Exp
 .\"
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd June 22, 2010
+.Dd September 19, 2006
 .Dt RACOON.CONF 5
 .Os
 .\"
@@ -152,7 +152,7 @@
 should switch.
 This can be a quoted user name or a numeric UID.
 .It Ic group Ar group ;
-The group the unprivileged instance of
+The group the unprivilegied instance of
 .Xr racoon 8 ,
 should switch.
 This can be a quoted group name or a numeric GID.
@@ -184,8 +184,7 @@
 .Ic certificate
 and
 .Ic script
-paths are mandatory.
-A
+paths are mandatory. A
 .Xr racoon 8
 restart is required if you want path changes to be taken into account.
 .Bl -tag -width Ds -compact
@@ -224,8 +223,7 @@
 Specifies file where to store PID of process.
 If path starts with
 .Pa /
-it is treated as an absolute path.
-Otherwise, it is treated as a relative
+it is treated as an absolute path. Otherwise, it is treated as a relative 
 path to the VARRUN directory specified at compilation time.
 Default is
 .Pa racoon.pid .
@@ -237,6 +235,12 @@
 Specifies other configuration files to be included.
 .El
 .\"
+.Ss Identifier Specification
+is obsolete.
+It must be defined at each
+.Ic remote
+directive.
+.\"
 .Ss Timer Specification
 .Bl -tag -width Ds -compact
 .It Ic timer { Ar statements Ic }
@@ -315,14 +319,12 @@
 .Ar owner ,
 and
 .Ar group
-values specify the socket path, owner, and group.
-They must be quoted.
+values specify the socket path, owner, and group. They must be quoted.
 The defaults are
 .Pa /var/racoon/racoon.sock ,
 UID 0, and GID 0.
 .Ar mode
-is the access mode in octal.
-The default is 0600.
+is the access mode in octal. The default is 0600.
 .It Ic adminsock disabled ;
 This directive tells racoon to not listen on the admin socket.
 .El
@@ -358,66 +360,22 @@
 .El
 .El
 .\"
-.Pp
-.Bl -tag -width Ds -compact
-.It Ic pfkey_buffer Ar kBytes
-Specifies the socket send/receive buffer size in kilobytes.
-Numerous kernel PF_KEY implementations have problems with dumping
-SAD/SDP with large amount of entries (this happens when 100s to
-1000s of tunnels are configured).
-.Pp
-The default value of 0 leaves everything at the OS-specific default value.
-If the default buffer size is greater than what is specified here racoon
-will not decrease it.
-.Pp
-This problem is known to be fixed in Linux 2.6.25 and later.
-.El
-.\"
 .Ss Remote Nodes Specifications
 .Bl -tag -width Ds -compact
-.It Ic remote Ar name Bo Ic inherit Ar parent_name Bc Ic { Ar statements Ic }
+.It Xo
+.Ic remote ( Ar address | Ic anonymous )
+.Bq Bq Ar port
+.Bq Ic inherit Ar parent
+.Ic { Ar statements Ic }
+.Xc
 Specifies the IKE phase 1 parameters for each remote node.
-.Pp
-If connection is initiated using racoonctl, a unique match using the
-remote IP must be found or the remote block name has to be given.
-For received acquires (kernel notices traffic requiring a new SA) the
-remote IP and remoteid from matching sainfo block are used to decide
-the remoteblock.
-If no uniquely matching remoteblock is found using
-these criteria, no connection attempt is done.
-.Pp
-When acting as responder, racoon picks the first proposal that has one
-or more acceptable remote configurations.
-When determining if a remote
-specification is matching the following information is checked:
-.Bl -bullet -width Ds -compact
-.It
-The remote IP is checked against
-.Ic remote_address .
-.It
-ISAKMP exchange type is checked against
-.Ic exchange_mode .
-.It
-ISAKMP SA attributes must match a
-.Ic proposal
-block.
-.It
-The remote identity is matched against
-.Ic peers_identifier
-if
-.Ic verify_identifier
-is on.
-.It
-If a certificate request was received, it must match the issuer of
-.Ic "certificate_type x509"
-certificate.
-If certificate request without issuer name was sent, the
-.Ic match_empty_cr
-parameter specifies whether or not remote block matches.
-.El
-.Pp
-Similarly, NAT-T is enabled if any of the initial remote configuration
-candidates allow NAT-T.
+The default port is 500.
+If
+.Ic anonymous
+is specified, the statements will apply to any peer that does not match a
+more specific
+.Ic remote
+directive.
 .Pp
 Sections with
 .Ic inherit Ar parent
@@ -435,9 +393,6 @@
 .Pp
 .Bl -tag -width Ds -compact
 .\"
-.It Ic remote_address Ar address ;
-Defines the IP address of the peer.
-.\"
 .It Ic exchange_mode ( main | aggressive | base ) ;
 Defines the exchange mode for phase 1 when racoon is the initiator.
 It also means the acceptable exchange mode when racoon is the responder.
@@ -453,7 +408,14 @@
 Means to use SIT_IDENTITY_ONLY as specified in RFC 2407.
 You can omit this statement.
 .\"
-.It Ic my_identifier Bo Ar qualifier Bc Ar idtype ... ;
+.It Ic identifier Ar idtype ;
+This statment is obsolete. Instead, use
+.Ic my_identifier .
+.\"
+.It Xo
+.Ic my_identifier Bq Ar qualifier
+.Ar idtype ... ;
+.Xc
 Specifies the identifier sent to the remote host
 and the type to use in the phase 1 negotiation.
 .Ic address, fqdn , user_fqdn , keyid ,
@@ -478,7 +440,10 @@
 The type is a USER_FQDN (user fully-qualified domain name).
 .It Ic my_identifier Ic fqdn Ar string ;
 The type is a FQDN (fully-qualified domain name).
-.It Ic my_identifier Ic keyid Bo Ic file Bc Ar file ;
+.It Xo
+.Ic my_identifier Ic keyid Bq Ic file
+.Ar file ;
+.Xc
 The type is a KEY_ID, read from the file.
 .It Ic my_identifier Ic keyid Ic tag Ar string ;
 The type is a KEY_ID, specified in the quoted string.
@@ -517,13 +482,6 @@
 identifier may specified as
 .Ic *
 to match any value (e.g. "C=XX, O=MyOrg, OU=*, CN=Mine").
-The format of the
-specification should correspond to RFC 2253; in particular, commas and certain
-other characters -
-.Ic ,=+\*[Lt]\*[Gt]#;
-- may be included in a name by preceeding them with a backslash "\e", and
-arbitrary characters may be inserted in a name with the "\enn" escape, where
-nn is the hex representation of the ascii value of the desired character.
 Alternative acceptable peer identifiers may be specified by repeating the
 .Ic peers_identifier
 statement.
@@ -551,9 +509,7 @@
 .Bl -tag -width Ds -compact
 .It Ic plain_rsa Ar privkeyfile ;
 .Ar privkeyfile
-means a file name of a private key generated by
-.Xr plainrsa-gen 8 .
-Required
+means a file name of a private key generated by plainrsa-gen(8).  Required
 for RSA authentication.
 .El
 .It Ic ca_type Ar cacertspec ;
@@ -597,20 +553,16 @@
 .Xr racoon 8
 will expect
 .Ar pubkeyfile
-to be the peer's public key that was generated by
-.Xr plainrsa-gen 8 .
+to be the peer's public key that was generated
+by plainrsa-gen(8).
 .\"
 .It Ic script Ar script Ic phase1_up
 .It Ic script Ar script Ic phase1_down
-.It Ic script Ar script Ic phase1_dead
-Shell scripts that get executed when a phase 1 SA goes up or down, or
-when it is detected as dead by DPD.
-All scripts get either
+Shell scripts that get executed when a phase 1 SA goes up or down.
+Both scripts get either
 .Ic phase1_up
-,
-.Ic phase1_down
 or
-.Ic phase1_dead
+.Ic phase1_down
 as first argument, and the following
 variables are set in their environment:
 .Bl -tag -width Ds -compact
@@ -622,8 +574,6 @@
 The remote address of the phase 1 SA.
 .It Ev REMOTE_PORT
 The remote port used for IKE for the phase 1 SA.
-.It Ev REMOTE_ID
-The remote identity received in IKE for the phase 1 SA.
 .El
 The following variables are only set if
 .Ic mode_cfg
@@ -654,10 +604,6 @@
 The space separated list of IPv4 addresses and masks (address slash mask)
 that define the networks to be considered local, and thus excluded from the
 tunnels ; obtained by ISAKMP mode config.
-.It SPLIT_INCLUDE_CIDR
-Same as SPLIT_INCLUDE, with netmasks in CIDR notation.
-.It SPLIT_LOCAL_CIDR
-Same as SPLIT_LOCAL, with netmasks in CIDR notation.
 .It DEFAULT_DOMAIN
 The DNS default domain name obtained by ISAKMP mode config.
 .El
@@ -671,21 +617,16 @@
 If you do not want to send a certificate request, set this to off.
 The default is on.
 .\"
-.It Ic match_empty_cr (on | off) ;
-Specifies whether this remote block is a valid match when a non-specific
-certificate request is received.
-The default is on.
-.\"
 .It Ic verify_cert (on | off) ;
 By default, the identifier sent by the remote host (as specified in its
 .Ic my_identifier
 statement) is compared with the credentials in the certificate
 used to authenticate the remote host as follows:
 .Bl -tag -width Ds -compact
-.It Type Ic asn1dn :
+.It Type Ic asn1dn:
 The entire certificate subject name is compared with the identifier,
 e.g. "C=XX, O=YY, ...".
-.It Type Ic address, fqdn, or user_fqdn :
+.It Type Ic address, fqdn, or user_fqdn:
 The certificate's subjectAltName is compared with the identifier.
 .El
 If the two do not match the negotiation will fail.
@@ -751,7 +692,7 @@
 It is useful for a server.
 .\"
 .It Ic proposal_check Ar level ;
-Specifies the action of lifetime length, key length, and PFS of the phase 2
+Specifies the action of lifetime length, key length and PFS of the phase 2
 selection on the responder side, and the action of lifetime check in
 phase 1.
 The default level is
@@ -871,22 +812,6 @@
 The default value is
 .Ic 5 .
 .\"
-.It Ic rekey (on | off | force) ;
-Enable automatic renegotiation of expired phase1 when there are non-dying
-phase2 SAs.
-Possible values are:
-.Bl -tag -width Ds -compact
-.It Ic force
-Rekeying is done unconditionally.
-.It Ic on
-Rekeying is done only if DPD monitoring is active.
-This is the default.
-.It Ic off
-No automatic rekeying.
-Do note that turning off automatic rekeying will
-result in inaccurate DPD monitoring.
-.El
-.\"
 .It Ic nonce_size Ar number ;
 define the byte size of nonce value.
 Racoon can send any value although
@@ -894,11 +819,13 @@
 The default size is 16 bytes.
 .\"
 .It Ic ph1id Ar number ;
-An optional number to identify the remote proposal and to link it
+An optionnal number to identify the remote proposal and to link it
 only with sainfos who have the same number.
 Defaults to 0.
 .\"
-.It Ic proposal { Ar sub-substatements Ic }
+.It Xo
+.Ic proposal { Ar sub-substatements Ic }
+.Xc
 .Bl -tag -width Ds -compact
 .\"
 .It Ic encryption_algorithm Ar algorithm ;
@@ -961,35 +888,30 @@
 command.
 .El
 .El
-.Pp
-.It Ic remote Po Ar address | Ic anonymous Pc Bo Bo Ar port Bc Bc \
-Bo Ic inherit Ar parent Bc Ic { Ar statements Ic }
-Deprecated format of specifying a remote block.
-This will be removed in future.
-It is a remnant from time when remote block was decided
-solely based on the peers IP address.
-.Pp
-This is equivalent to:
-.Bd -literal -offset
-remote "address" [inherit "parent-address"] {
-	remote_address address;
-}
-.Ed
 .El
 .\"
+.Ss Policy Specifications
+The policy directive is obsolete, policies are now in the SPD.
+.Xr racoon 8
+will obey the policy configured into the kernel by
+.Xr setkey 8 ,
+and will construct phase 2 proposals by combining
+.Ic sainfo
+specifications in
+.Nm ,
+and policies in the kernel.
+.\"
 .Ss Sainfo Specifications
 .Bl -tag -width Ds -compact
-.It Ic sainfo Po Ar local_id | Ic anonymous Pc \
-Po Ar remote_id | Ic clientaddr | Ic anonymous Pc \
-Bo Ic from Ar idtype Bo Ar string Bc Bc Bo Ic group Ar string Bc \
-Ic { Ar statements Ic }
-Defines the parameters of the IKE phase 2 (IPsec-SA establishment).
-.Pp
-The
-.Ar local_id
+.It Xo
+.Ic sainfo ( Ar source_id destination_id | Ar source_id Ic anonymous | Ic anonymous Ar destination_id | Ic anonymous ) [ from Ar idtype [ Ar string ] ] [ Ic group Ar string ]
+.Ic { Ar statements Ic }
+.Xc
+defines the parameters of the IKE phase 2 (IPsec-SA establishment).
+.Ar source_id
 and
-.Ar remote_id
-strings are constructed like:
+.Ar destination_id
+are constructed like:
 .Pp
 .Ic address Ar address
 .Bq Ic / Ar prefix
@@ -1003,11 +925,17 @@
 .Bq Ic [ Ar port ]
 .Ar ul_proto
 .Pp
-An id string should be expressed to match the exact value of an ID payload.
+or
+.Pp
+.Ar idtype Ar string
+.Pp
+An id string should be expressed to match the exact value of an ID payload
+(source is the local end, destination is the remote end).
 This is not like a filter rule.
 For example, if you define 3ffe:501:4819::/48 as
-.Ar local_id .
+.Ar source_id .
 3ffe:501:4819:1000:/64 will not match.
+.Pp
 In the case of a longest prefix (selecting a single host),
 .Ar address
 instructs to send ID type of ADDRESS while
@@ -1015,24 +943,7 @@
 instructs to send ID type of SUBNET.
 Otherwise, these instructions are identical.
 .Pp
-The
-.Ic anonymous
-keyword can be used to match any id.
-The
-.Ic clientaddr
-keyword can be used to match a remote id that is equal to either the peer
-ip address or the mode_cfg ip address (if assigned).
-This can be useful
-to restrict policy generation when racoon is acting as a client gateway
-for peers with dynamic ip addresses.
-.Pp
-The
-.Ic from
-keyword allows an sainfo to only match for peers that use a specific phase1
-id value during authentication.
-The
-.Ic group
-keyword allows an XAuth group membership check to be performed
+The group keyword allows an XAuth group membership check to be performed
 for this sainfo section.
 When the mode_cfg auth source is set to
 .Ic system
@@ -1066,6 +977,10 @@
 Sainfos will only be used if their remoteid matches the ph1id of the
 remote section used for phase 1.
 Defaults to 0, which is also the default for ph1id.
+.\"
+.It Ic my_identifier Ar idtype ... ;
+is obsolete.
+It does not make sense to specify an identifier in the phase 2.
 .El
 .\"
 .Pp
@@ -1122,7 +1037,7 @@
 .Ar level
 is one of following:
 .Ic error , warning , notify , info , debug
-or
+and
 .Ic debug2 .
 The default is
 .Ic info .
@@ -1176,10 +1091,8 @@
 means to use a RADIUS server.
 It works only if
 .Xr racoon 8
-was built with libradius support.
-Radius configuration is handled by statements in the
-.Ic radiuscfg
-section.
+was built with libradius support. Radius configuration is hanlded by
+.Xr radius.conf 5 .
 .Ar pam
 means to use PAM.
 It works only if
@@ -1189,8 +1102,8 @@
 means to use LDAP.
 It works only if
 .Xr racoon 8
-was built with libldap support.
-LDAP configuration is handled by statements in the
+was built with libldap support. LDAP configuration is handled by
+statements in the
 .Ic ldapcfg
 section.
 .It Ic auth_groups Ar "group1", ... ;
@@ -1198,7 +1111,7 @@
 When defined, the authenticating user must be a member of at least one
 group for Xauth to succeed.
 .It Ic group_source (system | ldap) ;
-Specifies the source for group validation of users through Xauth.
+Specifies the source for group validataion of users through Xauth.
 .Ar system
 means to use the Unix user database.
 This is the default.
@@ -1224,10 +1137,9 @@
 means to use a RADIUS server.
 It works only if
 .Xr racoon 8
-was built with libradius support and requires RADIUS authentication.
-RADIUS configuration is handled by statements in the
-.Ic radiuscfg
-section.
+was built with libradius support and requires RADIUS authentiation.
+RADIUS configuration is handled by
+.Xr radius.conf 5 .
 .Ar ldap
 means to use an LDAP server.
 It works only if
@@ -1252,9 +1164,8 @@
 It works only if
 .Xr racoon 8
 was built with libradius support and requires RADIUS authentication.
-RADIUS configuration is handled by statements in the
-.Ic radiuscfg
-section.
+RADIUS configuration is handled by
+.Xr radius.conf 5 .
 Specifying
 .Ar pam
 enables PAM accounting.
@@ -1287,13 +1198,12 @@
 .Ic dns4
 lines.
 .It Ic wins4 Ar addresses ;
-A list of IPv4 address for WINS servers.
-The keyword
+A list of IPv4 address for WINS servers. The keyword
 .It nbns4
 can also be used as an alias for
 .It wins4 .
 .It Ic split_network (include | local_lan) Ar network/mask, ...
-The network configuration to send, in CIDR notation (e.g. 192.168.1.0/24).
+The network configuration to send, in cidr notation (e.g. 192.168.1.0/24).
 If
 .Ic include
 is specified, the tunnel should be only used to encrypt the indicated
@@ -1345,11 +1255,11 @@
 The host name or ip address of the ldap server.
 The default is
 .Ic localhost .
-.It Ic port Ar number ;
+.It Ic port Ar number;
 The port that the ldap server is configured to listen on.
 The default is
 .Ic 389 .
-.It Ic base Ar distinguished name ;
+.It Ic base Ar distinguished name;
 The ldap search base.
 This option has no default value.
 .It Ic subtree (on | off) ;
@@ -1357,20 +1267,20 @@
 Otherwise, use the one level search scope.
 The default is
 .Ic off .
-.It Ic bind_dn Ar distinguished name ;
-The user dn used to optionally bind as before performing ldap search operations.
+.It Ic bind_dn Ar distinguised name;
+The user dn used to optionaly bind as before performing ldap search operations.
 If this option is not specified, anonymous binds are used.
-.It Ic bind_pw Ar string ;
+.It Ic bind_pw Ar string;
 The password used when binding as
 .Ic bind_dn .
-.It Ic attr_user Ar attribute name ;
+.It Ic attr_user Ar attribute name;
 The attribute used to specify a users name in an ldap directory.
 For example,
 if a user dn is "cn=jdoe,dc=my,dc=net" then the attribute would be "cn".
 The default value is
 .Ic cn .
-.It Ic attr_addr Ar attribute name ;
-.It Ic attr_mask Ar attribute name ;
+.It Ic attr_addr Ar attribute name;
+.It Ic attr_mask Ar attribute name;
 The attributes used to specify a users network address and subnet mask in an
 ldap directory.
 These values are forwarded during mode_cfg negotiation when
@@ -1379,54 +1289,18 @@
 .Ic racoon-address
 and
 .Ic racoon-netmask .
-.It Ic attr_group Ar attribute name ;
+.It Ic attr_group Ar attribute name;
 The attribute used to specify a group name in an ldap directory.
 For example,
 if a group dn is "cn=users,dc=my,dc=net" then the attribute would be "cn".
 The default value is
 .Ic cn .
-.It Ic attr_member Ar attribute name ;
+.It Ic attr_member Ar attribute name;
 The attribute used to specify group membership in an ldap directory.
 The default value is
 .Ic member .
 .El
 .El
-.Ss Radius configuration settings
-.Bl -tag -width Ds -compact
-.It Ic radiuscfg { Ar statements Ic }
-Defines the parameters that will be used to communicate with radius
-servers for
-.Ic xauth
-authentication.
-If radius is selected as the xauth authentication or accounting
-source and no servers are defined in this section, settings from
-the system
-.Xr radius.conf 5
-configuration file will be used instead.
-.Pp
-The following are valid statements:
-.Bl -tag -width Ds -compact
-.It Ic auth Ar (hostname | address) [port] sharedsecret ;
-The host name or ip address, optional port value and shared secret value
-of a radius authentication server.
-Up to 5 radius authentication servers
-may be specified using multiple lines.
-.It Ic acct Ar (hostname | address) [port] sharedsecret ;
-The host name or ip address, optional port value and shared secret value
-of a radius accounting server.
-Up to 5 radius accounting servers may be
-specified using multiple lines.
-.It Ic timeout Ar seconds ;
-The timeout for receiving replies from radius servers.
-The default is
-.Ic 3 .
-.It Ic retries Ar count ;
-The maximum number of repeated requests to make before giving up
-on a radius server.
-The default is
-.Ic 3 .
-.El
-.El
 .Ss Special directives
 .Bl -tag -width Ds -compact
 .It Ic complex_bundle (on | off) ;
diff --git a/src/racoon/racoonctl.8 b/src/racoon/racoonctl.8
index 697f3ed..b27b188 100644
--- a/src/racoon/racoonctl.8
+++ b/src/racoon/racoonctl.8
@@ -1,4 +1,4 @@
-.\"	$NetBSD: racoonctl.8,v 1.22 2009/03/12 14:01:09 wiz Exp $
+.\"	$NetBSD: racoonctl.8,v 1.13 2006/09/09 16:22:10 manu Exp $
 .\"
 .\" Id: racoonctl.8,v 1.6 2006/05/07 21:32:59 manubsd Exp
 .\"
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd March 12, 2009
+.Dd November 16, 2004
 .Dt RACOONCTL 8
 .Os
 .\"
@@ -39,49 +39,34 @@
 .\"
 .Sh SYNOPSIS
 .Nm
-.Op opts
 reload-config
 .Nm
-.Op opts
 show-schedule
 .Nm
-.Op opts
+.Op Fl l Op Fl l
 show-sa
 .Op isakmp|esp|ah|ipsec
 .Nm
-.Op opts
-get-sa-cert
-.Op inet|inet6
-.Ar src dst
-.Nm
-.Op opts
 flush-sa
 .Op isakmp|esp|ah|ipsec
 .Nm
-.Op opts
 delete-sa
 .Ar saopts
 .Nm
-.Op opts
 establish-sa
-.Op Fl w
-.Op Fl n Ar remoteconf
 .Op Fl u Ar identity
 .Ar saopts
 .Nm
-.Op opts
 vpn-connect
-.Op Fl u Ar identity
+.Op Fl u identity
 .Ar vpn_gateway
 .Nm
-.Op opts
 vpn-disconnect
 .Ar vpn_gateway
 .Nm
-.Op opts
 show-event
+.Op Fl l
 .Nm
-.Op opts
 logout-user
 .Ar login
 .\"
@@ -100,19 +85,6 @@
 .Xr racoon 8
 behavior, so do that with caution.
 .Pp
-The following general options are available:
-.Bl -tag -width Ds
-.It Fl d
-Debug mode.
-Hexdump sent admin port commands.
-.It Fl l
-Increase verbosity.
-Mainly for show-sa command.
-.It Fl s Ar socket
-Specify unix socket name used to connecting racoon.
-.El
-.\"
-.Pp
 The following commands are available:
 .Bl -tag -width Ds
 .It reload-config
@@ -127,41 +99,33 @@
 Use
 .Fl l
 to increase verbosity.
-.It get-sa-cert Oo inet|inet6 Oc Ar src dst
-Output the raw certificate that was used to authenticate the phase 1
-matching
-.Ar src
-and
-.Ar dst .
 .It flush-sa Op isakmp|esp|ah|ipsec
 is used to flush all SAs if no SA class is provided, or a class of SAs,
 either ISAKMP SAs, IPsec ESP SAs, IPsec AH SAs, or all IPsec SAs.
-.It establish-sa Oo Fl w Oc Oo Fl n Ar remoteconf Oc Oo Fl u Ar username \
-Oc Ar saopts
+.It Xo establish-sa
+.Oo Fl u Ar username
+.Oc Ar saopts
+.Xc
 Establish an SA, either an ISAKMP SA, IPsec ESP SA, or IPsec AH SA.
 The optional
 .Fl u Ar username
 can be used when establishing an ISAKMP SA while hybrid auth is in use.
-The exact remote block to use can be specified with
-.Fl n Ar remoteconf .
 .Nm
 will prompt you for the password associated with
 .Ar username
 and these credentials will be used in the Xauth exchange.
 .Pp
-Specifying
-.Fl w
-will make racoonctl wait until the SA is actually established or
-an error occurs.
-.Pp
 .Ar saopts
 has the following format:
 .Bl -tag -width Bl
 .It isakmp {inet|inet6} Ar src Ar dst
 .It {esp|ah} {inet|inet6} Ar src/prefixlen/port Ar dst/prefixlen/port
-{icmp|tcp|udp|gre|any}
+{icmp|tcp|udp|any}
 .El
-.It vpn-connect Oo Fl u Ar username Oc Ar vpn_gateway
+.It Xo vpn-connect
+.Oo Fl u Ar username
+.Oc Ar vpn_gateway
+.Xc
 This is a particular case of the previous command.
 It will establish an ISAKMP SA with
 .Ar vpn_gateway .
@@ -171,9 +135,16 @@
 This is a particular case of the previous command.
 It will kill all SAs associated with
 .Ar vpn_gateway .
-.It show-event
-Listen for all events reported by
-.Xr racoon 8 .
+.It show-event Op Fl l
+Dump all events reported by
+.Xr racoon 8 ,
+then quit.
+The
+.Fl l
+flag causes
+.Nm
+to not stop once all the events have been read, but rather to loop
+awaiting and reporting new events.
 .It logout-user Ar login
 Delete all SA established on behalf of the Xauth user
 .Ar login .
diff --git a/src/racoon/racoonctl.c b/src/racoon/racoonctl.c
index da28ecd..1dd26f0 100644
--- a/src/racoon/racoonctl.c
+++ b/src/racoon/racoonctl.c
@@ -1,10 +1,9 @@
-/*	$NetBSD: racoonctl.c,v 1.18 2010/11/12 09:08:26 tteras Exp $	*/
+/*	$NetBSD: racoonctl.c,v 1.7.6.2 2009/04/20 13:32:57 tteras Exp $	*/
 
 /*	Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2008 Timo Teras.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -93,7 +92,6 @@
 static vchar_t *f_reload __P((int, char **));
 static vchar_t *f_getsched __P((int, char **));
 static vchar_t *f_getsa __P((int, char **));
-static vchar_t *f_getsacert __P((int, char **));
 static vchar_t *f_flushsa __P((int, char **));
 static vchar_t *f_deletesa __P((int, char **));
 static vchar_t *f_exchangesa __P((int, char **));
@@ -106,59 +104,59 @@
 
 struct cmd_tag {
 	vchar_t *(*func) __P((int, char **));
+	int cmd;
 	char *str;
 } cmdtab[] = {
-	{ f_reload,	"reload-config" },
-	{ f_reload,	"rc" },
-	{ f_getsched,	"show-schedule" },
-	{ f_getsched,	"sc" },
-	{ f_getsa,	"show-sa" },
-	{ f_getsa,	"ss" },
-	{ f_getsacert,	"get-cert" },
-	{ f_getsacert,	"gc" },
-	{ f_flushsa,	"flush-sa" },
-	{ f_flushsa,	"fs" },
-	{ f_deletesa,	"delete-sa" },
-	{ f_deletesa,	"ds" },
-	{ f_exchangesa,	"establish-sa" },
-	{ f_exchangesa,	"es" },
-	{ f_vpnc,	"vpn-connect" },
-	{ f_vpnc,	"vc" },
-	{ f_vpnd,	"vpn-disconnect" },
-	{ f_vpnd,	"vd" },
-	{ f_getevt,	"show-event" },
-	{ f_getevt,	"se" },
+	{ f_reload,	ADMIN_RELOAD_CONF,	"reload-config" },
+	{ f_reload,	ADMIN_RELOAD_CONF,	"rc" },
+	{ f_getsched,	ADMIN_SHOW_SCHED,	"show-schedule" },
+	{ f_getsched,	ADMIN_SHOW_SCHED,	"sc" },
+	{ f_getsa,	ADMIN_SHOW_SA,		"show-sa" },
+	{ f_getsa,	ADMIN_SHOW_SA,		"ss" },
+	{ f_flushsa,	ADMIN_FLUSH_SA,		"flush-sa" },
+	{ f_flushsa,	ADMIN_FLUSH_SA,		"fs" },
+	{ f_deletesa,	ADMIN_DELETE_SA,	"delete-sa" },
+	{ f_deletesa,	ADMIN_DELETE_SA,	"ds" },
+	{ f_exchangesa,	ADMIN_ESTABLISH_SA,	"establish-sa" },
+	{ f_exchangesa,	ADMIN_ESTABLISH_SA,	"es" },
+	{ f_vpnc,	ADMIN_ESTABLISH_SA,	"vpn-connect" },
+	{ f_vpnc,	ADMIN_ESTABLISH_SA,	"vc" },
+	{ f_vpnd,	ADMIN_DELETE_ALL_SA_DST,"vpn-disconnect" },
+	{ f_vpnd,	ADMIN_DELETE_ALL_SA_DST,"vd" },
+	{ f_getevt,	ADMIN_SHOW_EVT,		"show-event" },
+	{ f_getevt,	ADMIN_SHOW_EVT,		"se" },
 #ifdef ENABLE_HYBRID
-	{ f_logoutusr,	"logout-user" },
-	{ f_logoutusr,	"lu" },
+	{ f_logoutusr,	ADMIN_LOGOUT_USER,	"logout-user" },
+	{ f_logoutusr,	ADMIN_LOGOUT_USER,	"lu" },
 #endif
-	{ NULL, NULL },
+	{ NULL, 0, NULL },
 };
 
 struct evtmsg {
 	int type;
 	char *msg;
+	enum { UNSPEC, ERROR, INFO } level;
 } evtmsg[] = {
-	{ EVT_RACOON_QUIT,		"Racoon terminated" },
-
-	{ EVT_PHASE1_UP,		"Phase 1 established" },
-	{ EVT_PHASE1_DOWN,		"Phase 1 deleted" },
-	{ EVT_PHASE1_NO_RESPONSE,	"Phase 1 error: peer not responding" },
-	{ EVT_PHASE1_NO_PROPOSAL,	"Phase 1 error: no proposal chosen" },
-	{ EVT_PHASE1_AUTH_FAILED,
-	  "Phase 1 error: authentication failed (bad certificate?)" },
-	{ EVT_PHASE1_DPD_TIMEOUT,	"Phase 1 error: dead peer detected" },
-	{ EVT_PHASE1_MODE_CFG,		"Phase 1 mode configuration done" },
-	{ EVT_PHASE1_XAUTH_SUCCESS,	"Phase 1 Xauth succeeded" },
-	{ EVT_PHASE1_XAUTH_FAILED,	"Phase 1 Xauth failed" },
-
-	{ EVT_PHASE2_NO_PHASE1,		"Phase 2 error: no suitable phase 1" },
-	{ EVT_PHASE2_UP,		"Phase 2 established" },
-	{ EVT_PHASE2_DOWN,		"Phase 2 deleted" },
-	{ EVT_PHASE2_NO_RESPONSE,	"Phase 2 error: no response" },
+	{ EVTT_PHASE1_UP, "Phase 1 established", INFO },
+	{ EVTT_PHASE1_DOWN, "Phase 1 deleted", INFO },
+	{ EVTT_XAUTH_SUCCESS, "Xauth exchange passed", INFO },
+	{ EVTT_ISAKMP_CFG_DONE, "ISAKMP mode config done", INFO },
+	{ EVTT_PHASE2_UP, "Phase 2 established", INFO },
+	{ EVTT_PHASE2_DOWN, "Phase 2 deleted", INFO },
+	{ EVTT_DPD_TIMEOUT, "Peer not reachable anymore", ERROR },
+	{ EVTT_PEER_NO_RESPONSE, "Peer not responding", ERROR },
+	{ EVTT_PEER_DELETE, "Peer terminated security association", ERROR },
+	{ EVTT_RACOON_QUIT, "Raccon terminated", ERROR },
+	{ EVTT_OVERFLOW, "Event queue overflow", ERROR },
+	{ EVTT_XAUTH_FAILED, "Xauth exchange failed", ERROR },
+	{ EVTT_PEERPH1AUTH_FAILED, "Peer failed phase 1 authentication "
+	    "(certificate problem?)", ERROR },
+	{ EVTT_PEERPH1_NOPROP, "Peer failed phase 1 initiation "
+	    "(proposal problem?)", ERROR },
+	{ 0, NULL, UNSPEC },
+	{ EVTT_NO_ISAKMP_CFG, "No need for ISAKMP mode config ", INFO },
 };
 
-static vchar_t *get_proto_and_index __P((int, char **, u_int16_t *));
 static int get_proto __P((char *));
 static vchar_t *get_index __P((int, char **));
 static int get_family __P((char *));
@@ -186,7 +184,6 @@
 	{ IPPROTO_ICMP,	"icmp" },
 	{ IPPROTO_TCP,	"tcp" },
 	{ IPPROTO_UDP,	"udp" },
-	{ IPPROTO_GRE,	"gre" },
 	{ 0, NULL },
 };
 
@@ -196,13 +193,31 @@
 
 char *pname;
 int long_format = 0;
-int evt_quit_event = 0;
+
+#define EVTF_NONE		0x0000	/* Ignore any events */
+#define EVTF_LOOP		0x0001	/* Loop awaiting for new events */
+#define EVTF_CFG_STOP		0x0002	/* Stop after ISAKMP mode config */
+#define EVTF_CFG		0x0004	/* Print ISAKMP mode config info */
+#define EVTF_ALL		0x0008	/* Print any events */
+#define EVTF_PURGE		0x0010	/* Print all available events */
+#define EVTF_PH1DOWN_STOP	0x0020	/* Stop when phase 1 SA gets down */
+#define EVTF_PH1DOWN		0x0040	/* Print that phase 1 SA got down */
+#define EVTF_ERR		0x0080	/* Print any error */
+#define EVTF_ERR_STOP		0x0100	/* Stop on any error */
+
+int evt_filter = EVTF_NONE;
+time_t evt_start;
 
 void dump_isakmp_sa __P((char *, int));
 void dump_internal __P((char *, int));
 char *pindex_isakmp __P((isakmp_index *));
 void print_schedule __P((caddr_t, int));
-void print_evt __P((struct evt_async *));
+void print_evt __P((caddr_t, int));
+void print_cfg __P((caddr_t, int));
+void print_err __P((caddr_t, int));
+void print_ph1down __P((caddr_t, int));
+void print_ph1up __P((caddr_t, int));
+int evt_poll __P((void));
 char * fixed_addr __P((char *, char *, int));
 
 static void
@@ -210,23 +225,14 @@
 {
 	printf(
 "Usage:\n"
-"  %s [opts] reload-config\n"
-"  %s [opts] show-schedule\n"
-"  %s [opts] show-sa [protocol]\n"
-"  %s [opts] flush-sa [protocol]\n"
-"  %s [opts] delete-sa <saopts>\n"
-"  %s [opts] establish-sa [-u identity] [-n remoteconf] [-w] <saopts>\n"
-"  %s [opts] vpn-connect [-u identity] vpn_gateway\n"
-"  %s [opts] vpn-disconnect vpn_gateway\n"
-"  %s [opts] show-event\n"
-"  %s [opts] logout-user login\n"
+"  %s reload-config\n"
+"  %s [-l [-l]] show-sa [protocol]\n"
+"  %s flush-sa [protocol]\n"
+"  %s delete-sa <saopts>\n"
+"  %s establish-sa [-u identity] <saopts>\n"
+"  %s vpn-connect [-u identity] vpn_gateway\n"
+"  %s vpn-disconnect vpn_gateway\n"
 "\n"
-"General options:\n"
-"  -d		Debug: hexdump admin messages before sending\n"
-"  -l		Increase output verbosity (mainly for show-sa)\n"
-"  -s <socket>	Specify adminport socket to use (default: %s)\n"
-"\n"
-"Parameter specifications:\n"
 "    <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
 "        In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
 "\n"
@@ -234,10 +240,8 @@
 "            : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
 "                              <ul_proto>\n"
 "    <family>: \"inet\" or \"inet6\"\n"
-"    <ul_proto>: \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n"
-"\n",
-		pname, pname, pname, pname, pname, pname, pname, pname, pname, pname,
-		ADMINSOCK_PATH);
+"    <ul_proto>: \"icmp\", \"tcp\", \"udp\" or \"any\"\n",
+	pname, pname, pname, pname, pname, pname, pname);
 }
 
 /*
@@ -308,24 +312,54 @@
 
 	vfree(combuf);
 
-	do {
-		if (com_recv(&combuf) != 0)
-			goto bad;
-		if (handle_recv(combuf) != 0)
-			goto bad;
-		vfree(combuf);
-	} while (evt_quit_event != 0);
+	if (com_recv(&combuf) != 0)
+		goto bad;
+	if (handle_recv(combuf) != 0)
+		goto bad;
 
-	close(so);
+	vfree(combuf);
+
+	if (evt_filter != EVTF_NONE)
+		if (evt_poll() != 0)
+			goto bad;	
+	
 	exit(0);
 
-bad:
-	close(so);
-	if (errno == EEXIST)
-		exit(0);
+    bad:
 	exit(1);
 }
 
+int
+evt_poll(void) {
+	struct timeval tv;
+	vchar_t *recvbuf;
+	vchar_t *sendbuf;
+
+	if ((sendbuf = f_getevt(0, NULL)) == NULL)
+		errx(1, "Cannot make combuf");
+
+
+	while (evt_filter & (EVTF_LOOP|EVTF_PURGE)) {
+		/* handle_recv closes the socket time, so open it each time */
+		com_init();
+
+		if (com_send(sendbuf) != 0)
+			errx(1, "Cannot send combuf");
+
+		if (com_recv(&recvbuf) == 0) {
+			handle_recv(recvbuf);
+			vfree(recvbuf);
+		}
+
+		tv.tv_sec = 0;
+		tv.tv_usec = 10;
+		(void)select(0, NULL, NULL, NULL, &tv);
+	}
+
+	vfree(sendbuf);
+	return 0;
+}
+
 /* %%% */
 /*
  * return command buffer.
@@ -360,30 +394,24 @@
 }
 
 static vchar_t *
-make_request(u_int16_t cmd, u_int16_t proto, size_t len)
-{
-	vchar_t *buf;
-	struct admin_com *head;
-
-	buf = vmalloc(sizeof(struct admin_com) + len);
-	if (buf == NULL)
-		errx(1, "not enough core");
-
-	head = (struct admin_com *) buf->v;
-	head->ac_len = buf->l;
-	head->ac_cmd = ADMIN_FLAG_VERSION | cmd;
-	head->ac_version = 1;
-	head->ac_proto = proto;
-
-	return buf;
-}
-
-static vchar_t *
 f_reload(ac, av)
 	int ac;
 	char **av;
 {
-	return make_request(ADMIN_RELOAD_CONF, 0, 0);
+	vchar_t *buf;
+	struct admin_com *head;
+
+	buf = vmalloc(sizeof(*head));
+	if (buf == NULL)
+		errx(1, "not enough core");
+
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = ADMIN_RELOAD_CONF;
+	head->ac_errno = 0;
+	head->ac_proto = 0;
+
+	return buf;
 }
 
 static vchar_t *
@@ -391,11 +419,36 @@
 	int ac;
 	char **av;
 {
-	evt_quit_event = -1;
-	if (ac >= 1)
+	vchar_t *buf;
+	struct admin_com *head;
+
+	/*
+	 * There are 3 ways of getting here
+	 * 1) racoonctl vc => evt_filter = (EVTF_LOOP|EVTF_CFG| ... )
+	 * 2) racoonctl es => evt_filter = EVTF_NONE
+	 * 3) racoonctl es -l => evt_filter = EVTF_LOOP
+	 * Catch the second case: show-event is here to purge all
+	 */
+	if (evt_filter == EVTF_NONE)
+		evt_filter = (EVTF_ALL|EVTF_PURGE);
+
+	if ((ac >= 1) && (strcmp(av[0], "-l") == 0))
+		evt_filter |= EVTF_LOOP;
+
+	if (ac >= 2)
 		errx(1, "too many arguments");
 
-	return make_request(ADMIN_SHOW_EVT, 0, 0);
+	buf = vmalloc(sizeof(*head));
+	if (buf == NULL)
+		errx(1, "not enough core");
+
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = ADMIN_SHOW_EVT;
+	head->ac_errno = 0;
+	head->ac_proto = 0;
+
+	return buf;
 }
 
 static vchar_t *
@@ -403,7 +456,20 @@
 	int ac;
 	char **av;
 {
-	return make_request(ADMIN_SHOW_SCHED, 0, 0);
+	vchar_t *buf;
+	struct admin_com *head;
+
+	buf = vmalloc(sizeof(*head));
+	if (buf == NULL)
+		errx(1, "not enough core");
+
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = ADMIN_SHOW_SCHED;
+	head->ac_errno = 0;
+	head->ac_proto = 0;
+
+	return buf;
 }
 
 static vchar_t *
@@ -411,6 +477,8 @@
 	int ac;
 	char **av;
 {
+	vchar_t *buf;
+	struct admin_com *head;
 	int proto;
 
 	/* need protocol */
@@ -420,29 +488,15 @@
 	if (proto == -1)
 		errx(1, "unknown protocol %s", *av);
 
-	return make_request(ADMIN_SHOW_SA, proto, 0);
-}
-
-static vchar_t *
-f_getsacert(ac, av)
-	int ac;
-	char **av;
-{
-	vchar_t *buf, *index;
-	struct admin_com_indexes *com;
-
-	index = get_index(ac, av);
-	if (index == NULL)
-		return NULL;
-
-	com = (struct admin_com_indexes *) index->v;
-	buf = make_request(ADMIN_GET_SA_CERT, ADMIN_PROTO_ISAKMP, index->l);
+	buf = vmalloc(sizeof(*head));
 	if (buf == NULL)
-		errx(1, "Cannot allocate buffer");
+		errx(1, "not enough core");
 
-	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
-
-	vfree(index);
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = ADMIN_SHOW_SA;
+	head->ac_errno = 0;
+	head->ac_proto = proto;
 
 	return buf;
 }
@@ -463,7 +517,17 @@
 	if (proto == -1)
 		errx(1, "unknown protocol %s", *av);
 
-	return make_request(ADMIN_FLUSH_SA, proto, 0);
+	buf = vmalloc(sizeof(*head));
+	if (buf == NULL)
+		errx(1, "not enough core");
+
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = ADMIN_FLUSH_SA;
+	head->ac_errno = 0;
+	head->ac_proto = proto;
+
+	return buf;
 }
 
 static vchar_t *
@@ -472,6 +536,7 @@
 	char **av;
 {
 	vchar_t *buf, *index;
+	struct admin_com *head;
 	int proto;
 
 	/* need protocol */
@@ -501,11 +566,17 @@
 		return NULL;
 	}
 
-	buf = make_request(ADMIN_DELETE_SA, proto, index->l);
+	buf = vmalloc(sizeof(*head) + index->l);
 	if (buf == NULL)
 		goto out;
 
-	memcpy(buf->v + sizeof(struct admin_com), index->v, index->l);
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l + index->l;
+	head->ac_cmd = ADMIN_DELETE_SA;
+	head->ac_errno = 0;
+	head->ac_proto = proto;
+
+	memcpy(buf->v+sizeof(*head), index->v, index->l);
 
 out:
 	if (index != NULL)
@@ -520,17 +591,47 @@
 	char **av;
 {
 	vchar_t *buf, *index;
-	u_int16_t proto;
+	struct admin_com *head;
+	int proto;
 
-	index = get_proto_and_index(ac, av, &proto);
-	if (index == NULL)
+	/* need protocol */
+	if (ac < 1)
+		errx(1, "insufficient arguments");
+	proto = get_proto(*av);
+	if (proto == -1)
+		errx(1, "unknown protocol %s", *av);
+
+	/* get index(es) */
+	av++;
+	ac--;
+	switch (proto) {
+	case ADMIN_PROTO_ISAKMP:
+		index = get_index(ac, av);
+		if (index == NULL)
+			return NULL;
+		break;
+	case ADMIN_PROTO_AH:
+	case ADMIN_PROTO_ESP:
+		index = get_index(ac, av);
+		if (index == NULL)
+			return NULL;
+		break;
+	default:
+		errno = EPROTONOSUPPORT;
 		return NULL;
+	}
 
-	buf = make_request(ADMIN_DELETE_ALL_SA_DST, proto, index->l);
+	buf = vmalloc(sizeof(*head) + index->l);
 	if (buf == NULL)
 		goto out;
 
-	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l + index->l;
+	head->ac_cmd = ADMIN_DELETE_ALL_SA_DST;
+	head->ac_errno = 0;
+	head->ac_proto = proto;
+
+	memcpy(buf->v+sizeof(*head), index->v, index->l);
 
 out:
 	if (index != NULL)
@@ -545,14 +646,13 @@
 	char **av;
 {
 	vchar_t *buf, *index;
-	u_int16_t proto;
+	struct admin_com *head;
+	int proto;
 	int cmd = ADMIN_ESTABLISH_SA;
 	size_t com_len = 0;
 	char *id = NULL;
 	char *key = NULL;
-	char *remoteconf = NULL;
 	struct admin_com_psk *acp;
-	int wait = 0;
 
 	if (ac < 1)
 		errx(1, "insufficient arguments");
@@ -573,57 +673,48 @@
 		ac -= 2;
 	}
 
-	if (ac >= 2 && strcmp(av[0], "-n") == 0) {
-		/* Remoteconf name */
-		remoteconf = av[1];
-		av += 2;
-		ac -= 2;
-	}
+	/* need protocol */
+	if (ac < 1)
+		errx(1, "insufficient arguments");
+	if ((proto = get_proto(*av)) == -1)
+		errx(1, "unknown protocol %s", *av);
 
-	if (ac >= 1 && strcmp(av[0], "-w") == 0) {
-		wait = 1;
-		av++;
-		ac--;
-	}
-
-	index = get_proto_and_index(ac, av, &proto);
-	if (index == NULL)
-		return NULL;
-
-	if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
-	    remoteconf != NULL)
-		com_len += strlen(remoteconf) + 1;
-
-	if (wait) {
-		switch (proto) {
-		case ADMIN_PROTO_ISAKMP:
-			evt_quit_event = EVT_PHASE1_MODE_CFG;
-			break;
-		case ADMIN_PROTO_AH:
-		case ADMIN_PROTO_ESP:
-			evt_quit_event = EVT_PHASE2_UP;
-			break;
-		default:
-			errno = EPROTONOSUPPORT;
+	/* get index(es) */
+	av++;
+	ac--;
+	switch (proto) {
+	case ADMIN_PROTO_ISAKMP:
+		index = get_index(ac, av);
+		if (index == NULL)
 			return NULL;
-		}
+		break;
+	case ADMIN_PROTO_AH:
+	case ADMIN_PROTO_ESP:
+		index = get_index(ac, av);
+		if (index == NULL)
+			return NULL;
+		break;
+	default:
+		errno = EPROTONOSUPPORT;
+		return NULL;
 	}
 
-	com_len += index->l;
-	buf = make_request(cmd, proto, com_len);
-	if (buf == NULL)
+	com_len += sizeof(*head) + index->l;
+	if ((buf = vmalloc(com_len)) == NULL)
 		errx(1, "Cannot allocate buffer");
 
-	memcpy(buf->v+sizeof(struct admin_com), index->v, index->l);
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = cmd;
+	head->ac_errno = 0;
+	head->ac_proto = proto;
 
-	if (proto == ADMIN_PROTO_ISAKMP && cmd == ADMIN_ESTABLISH_SA &&
-	    remoteconf != NULL) {
-		strcpy(buf->v + sizeof(struct admin_com) + index->l,
-		       remoteconf);
-	} else if (id && key) {
+	memcpy(buf->v+sizeof(*head), index->v, index->l);
+
+	if (id && key) {
 		char *data;
 		acp = (struct admin_com_psk *)
-		    (buf->v + sizeof(struct admin_com) + index->l);
+		    (buf->v + sizeof(*head) + index->l);
 
 		acp->id_type = IDTYPE_USERFQDN;
 		acp->id_len = strlen(id) + 1;
@@ -658,7 +749,8 @@
 	if (ac < 1)
 		errx(1, "insufficient arguments");
 
-	evt_quit_event = EVT_PHASE1_MODE_CFG;
+	evt_filter = (EVTF_LOOP|EVTF_CFG|EVTF_CFG_STOP|EVTF_ERR|EVTF_ERR_STOP);
+	time(&evt_start);
 	
 	/* Optional -u identity */
 	if (strcmp(av[0], "-u") == 0) {
@@ -673,7 +765,7 @@
 	}
 
 	if (ac < 1)
-		errx(1, "VPN gateway required");
+		errx(1, "VPN gateway required");	
 	if (ac > 1)
 		warnx("Extra arguments");
 
@@ -718,11 +810,12 @@
 	char *idx;
 
 	if (ac < 1)
-		errx(1, "VPN gateway required");
+		errx(1, "VPN gateway required");	
 	if (ac > 1)
 		warnx("Extra arguments");
 
-	evt_quit_event = EVT_PHASE1_DOWN;
+	evt_filter = 
+	    (EVTF_PH1DOWN|EVTF_PH1DOWN_STOP|EVTF_LOOP|EVTF_ERR|EVTF_ERR_STOP);
 
 	nav[nac++] = isakmp;
 	nav[nac++] = inet;
@@ -739,6 +832,7 @@
 	char **av;
 {
 	vchar_t *buf;
+	struct admin_com *head;
 	char *user;
 	size_t userlen;
 
@@ -750,46 +844,22 @@
 	if ((user == NULL) || (userlen > LOGINLEN))
 		errx(1, "bad login (too long?)");
 
-	buf = make_request(ADMIN_LOGOUT_USER, 0, userlen);
+	buf = vmalloc(sizeof(*head) + userlen);
 	if (buf == NULL)
 		return NULL;
 
-	strncpy(buf->v + sizeof(struct admin_com), user, userlen);
+	head = (struct admin_com *)buf->v;
+	head->ac_len = buf->l;
+	head->ac_cmd = ADMIN_LOGOUT_USER;
+	head->ac_errno = 0;
+	head->ac_proto = 0;
+
+	strncpy((char *)(head + 1), user, userlen);
 
 	return buf;
 }
 #endif /* ENABLE_HYBRID */
 
-static vchar_t *
-get_proto_and_index(ac, av, proto)
-	int ac;
-	char **av;
-	u_int16_t *proto;
-{
-	vchar_t *index = NULL;
-
-	/* need protocol */
-	if (ac < 1)
-		errx(1, "insufficient arguments");
-	*proto = get_proto(*av);
-	if (*proto == (u_int16_t) -1)
-		errx(1, "unknown protocol %s", *av);
-
-	/* get index(es) */
-	av++;
-	ac--;
-	switch (*proto) {
-	case ADMIN_PROTO_ISAKMP:
-	case ADMIN_PROTO_AH:
-	case ADMIN_PROTO_ESP:
-		index = get_index(ac, av);
-		break;
-	default:
-		errno = EPROTONOSUPPORT;
-		break;
-	}
-	return index;
-}
 
 static int
 get_proto(str)
@@ -1267,32 +1337,84 @@
 
 
 void
-print_evt(evtdump)
-	struct evt_async *evtdump;
+print_evt(buf, len)
+	caddr_t buf;
+	int len;
 {
+	struct evtdump *evtdump = (struct evtdump *)buf;
 	int i;
 	char *srcstr;
 	char *dststr;
 	
-	for (i = 0; i < sizeof(evtmsg) / sizeof(evtmsg[0]); i++)
-		if (evtmsg[i].type == evtdump->ec_type)
-			break;
-
-	if (evtmsg[i].msg == NULL)
-		printf("Event %d: ", evtdump->ec_type);
+	for (i = 0; evtmsg[i].msg; i++)
+		if (evtmsg[i].type == evtdump->type)
+			break;				
+	
+	if (evtmsg[i].msg == NULL) 
+		printf("Event %d: ", evtdump->type);
 	else
 		printf("%s : ", evtmsg[i].msg);
 
-	if ((srcstr = saddr2str((struct sockaddr *)&evtdump->ec_ph1src)) == NULL)
+	if ((srcstr = saddr2str((struct sockaddr *)&evtdump->src)) == NULL)
 		printf("unknown");
-	else
+	else 
 		printf("%s", srcstr);
 	printf(" -> ");
-	if ((dststr = saddr2str((struct sockaddr *)&evtdump->ec_ph1dst)) == NULL)
+	if ((dststr = saddr2str((struct sockaddr *)&evtdump->dst)) == NULL)
 		printf("unknown");
-	else
+	else 
 		printf("%s", dststr);
 	printf("\n");
+
+	return;
+}
+
+void
+print_err(buf, len)
+	caddr_t buf;
+	int len;
+{
+	struct evtdump *evtdump = (struct evtdump *)buf;
+	int i;
+	
+	
+	for (i = 0; evtmsg[i].msg; i++)
+		if (evtmsg[i].type == evtdump->type)
+			break;				
+
+	if (evtmsg[i].level != ERROR)
+		return;
+	
+	if (evtmsg[i].msg == NULL) 
+		printf("Error: Event %d\n", evtdump->type);
+	else
+		printf("Error: %s\n", evtmsg[i].msg);
+
+	if (evt_filter & EVTF_ERR_STOP)
+		evt_filter &= ~EVTF_LOOP;
+
+	return;
+}
+
+/*
+ * Print a message when phase 1 SA goes down
+ */
+void
+print_ph1down(buf, len)
+	caddr_t buf;
+	int len;
+{
+	struct evtdump *evtdump = (struct evtdump *)buf;
+	
+	if (evtdump->type != EVTT_PHASE1_DOWN)
+		return;
+
+	printf("VPN connexion terminated\n");
+
+	if (evt_filter & EVTF_PH1DOWN_STOP)
+		evt_filter &= ~EVTF_LOOP;
+	
+	return;
 }
 
 /*
@@ -1303,14 +1425,15 @@
 	caddr_t buf;
 	int len;
 {
-	struct evt_async *evtdump = (struct evt_async *)buf;
+	struct evtdump *evtdump = (struct evtdump *)buf;
 	struct isakmp_data *attr;
 	char *banner = NULL;
 	struct in_addr addr4;
 	
 	memset(&addr4, 0, sizeof(addr4));
 
-	if (evtdump->ec_type != EVT_PHASE1_MODE_CFG)
+	if (evtdump->type != EVTT_ISAKMP_CFG_DONE && 
+	    evtdump->type != EVTT_NO_ISAKMP_CFG)
 		return;
 
 	len -= sizeof(*evtdump);
@@ -1363,12 +1486,12 @@
 			    (n + sizeof(*attr) + ntohs(attr->lorv));
 		}
 	}
-
-	if (len > 0)
+	
+	if (evtdump->type == EVTT_ISAKMP_CFG_DONE)
 		printf("Bound to address %s\n", inet_ntoa(addr4));
 	else
 		printf("VPN connexion established\n");
-
+	
 	if (banner) {
 		struct winsize win;
 		int col = 0;
@@ -1385,8 +1508,13 @@
 		printf("\n");
 		racoon_free(banner);
 	}
+	
+	if (evt_filter & EVTF_CFG_STOP)
+		evt_filter &= ~EVTF_LOOP;
+	
+	return;
 }
-
+	
 
 char *
 fixed_addr(addr, port, len)
@@ -1421,54 +1549,49 @@
 handle_recv(combuf)
 	vchar_t *combuf;
 {
-        struct admin_com *com;
+        struct admin_com h, *com;
         caddr_t buf;
         int len;
 
 	com = (struct admin_com *)combuf->v;
-	if (com->ac_cmd & ADMIN_FLAG_LONG_REPLY)
-		len = ((u_int32_t)com->ac_len) + (((u_int32_t)com->ac_len_high) << 16);
-	else
-		len = com->ac_len;
-	len -= sizeof(*com);
+	len = com->ac_len - sizeof(*com);
 	buf = combuf->v + sizeof(*com);
 
-	switch (com->ac_cmd & ~ADMIN_FLAG_LONG_REPLY) {
+	switch (com->ac_cmd) {
 	case ADMIN_SHOW_SCHED:
 		print_schedule(buf, len);
 		break;
 
 	case ADMIN_SHOW_EVT: {
-		struct evt_async *ec;
+		struct evtdump *evtdump;
 
-		/* We got no event? */
-		if (len == 0)
+		/* We got no event */
+		if (len == 0) {
+			/* If we were purging the queue, it is now done */
+			if (evt_filter & EVTF_PURGE)
+				evt_filter &= ~EVTF_PURGE;
+			break;
+		}
+
+		if (len < sizeof(struct evtdump))
+			errx(1, "Short buffer\n");		
+
+		/* Toss outdated events */
+		evtdump = (struct evtdump *)buf;
+		if (evtdump->timestamp < evt_start)
 			break;
 
-		if (len < sizeof(struct evt_async))
-			errx(1, "Short buffer\n");
-
-		ec = (struct evt_async *) buf;
-		if (evt_quit_event <= 0)
-			print_evt(ec);
-		else if (evt_quit_event == ec->ec_type) {
-			switch (ec->ec_type) {
-			case EVT_PHASE1_MODE_CFG:
-				print_cfg(ec, len);
-				break;
-			default:
-				print_evt(ec);
-				break;
-			}
-			evt_quit_event = 0;
-		}
+		if (evt_filter & EVTF_ALL)
+			print_evt(buf, len);
+		if (evt_filter & EVTF_ERR)
+			print_err(buf, len);
+		if (evt_filter & EVTF_CFG)
+			print_cfg(buf, len);
+		if (evt_filter & EVTF_PH1DOWN)
+			print_ph1down(buf, len);
 		break;
 	}
 
-	case ADMIN_GET_SA_CERT:
-		fwrite(buf, len, 1, stdout);
-		break;
-
 	case ADMIN_SHOW_SA:
 	   {
 		switch (com->ac_proto) {
@@ -1522,8 +1645,10 @@
 		break;
 	}
 
+	close(so);
 	return 0;
 
-bad:
+    bad:
+	close(so);
 	return -1;
 }
diff --git a/src/racoon/remoteconf.c b/src/racoon/remoteconf.c
index 74e386c..c9c803f 100644
--- a/src/racoon/remoteconf.c
+++ b/src/racoon/remoteconf.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: remoteconf.c,v 1.26 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: remoteconf.c,v 1.9.4.2 2008/06/18 07:30:19 mgrooms Exp $	*/
 
 /* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -63,7 +63,6 @@
 #endif
 #include "isakmp.h"
 #include "ipsec_doi.h"
-#include "crypto_openssl.h"
 #include "oakley.h"
 #include "remoteconf.h"
 #include "localconf.h"
@@ -76,307 +75,16 @@
 #include "algorithm.h"
 #include "nattraversal.h"
 #include "isakmp_frag.h"
-#include "handler.h"
 #include "genlist.h"
-#include "rsalist.h"
 
-typedef TAILQ_HEAD(_rmtree, remoteconf) remoteconf_tailq_head_t;
-static remoteconf_tailq_head_t rmtree, rmtree_save;
+static TAILQ_HEAD(_rmtree, remoteconf) rmtree, rmtree_save, rmtree_tmp;
 
-/*
+/* 
  * Script hook names and script hook paths
  */
-char *script_names[SCRIPT_MAX + 1] = {
-	"phase1_up", "phase1_down", "phase1_dead" };
+char *script_names[SCRIPT_MAX + 1] = { "phase1_up", "phase1_down" };
 
 /*%%%*/
-
-int
-rmconf_match_identity(rmconf, id_p)
-	struct remoteconf *rmconf;
-	vchar_t *id_p;
-{
-	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *) id_p->v;
-	struct sockaddr *sa;
-	caddr_t sa1, sa2;
-	vchar_t ident;
-	struct idspec *id;
-	struct genlist_entry *gpb;
-
-	/* compare with the ID if specified. */
-	if (!genlist_next(rmconf->idvl_p, 0))
-		return 0;
-
-	for (id = genlist_next(rmconf->idvl_p, &gpb); id; id = genlist_next(0, &gpb)) {
-		/* No ID specified in configuration, so it is ok */
-		if (id->id == 0)
-			return 0;
-
-		/* check the type of both IDs */
-		if (id->idtype != doi2idtype(id_b->type))
-			continue;  /* ID type mismatch */
-
-		/* compare defined ID with the ID sent by peer. */
-		switch (id->idtype) {
-		case IDTYPE_ASN1DN:
-			ident.v = id_p->v + sizeof(*id_b);
-			ident.l = id_p->l - sizeof(*id_b);
-			if (eay_cmp_asn1dn(id->id, &ident) == 0)
-				return 0;
-			break;
-		case IDTYPE_ADDRESS:
-			sa = (struct sockaddr *)id->id->v;
-			sa2 = (caddr_t)(id_b + 1);
-			switch (sa->sa_family) {
-			case AF_INET:
-				if (id_p->l - sizeof(*id_b) != sizeof(struct in_addr))
-					continue;  /* ID value mismatch */
-				sa1 = (caddr_t) &((struct sockaddr_in *)sa)->sin_addr;
-				if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0)
-					return 0;
-				break;
-#ifdef INET6
-			case AF_INET6:
-				if (id_p->l - sizeof(*id_b) != sizeof(struct in6_addr))
-					continue;  /* ID value mismatch */
-				sa1 = (caddr_t) &((struct sockaddr_in6 *)sa)->sin6_addr;
-				if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0)
-					return 0;
-				break;
-#endif
-			default:
-				break;
-			}
-			break;
-		default:
-			if (memcmp(id->id->v, id_b + 1, id->id->l) == 0)
-				return 0;
-			break;
-		}
-	}
-
-	plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n");
-	if (rmconf->verify_identifier)
-		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
-
-	return 0;
-}
-
-static int
-rmconf_match_etype_and_approval(rmconf, etype, approval)
-	struct remoteconf *rmconf;
-	int etype;
-	struct isakmpsa *approval;
-{
-	struct isakmpsa *p;
-
-	if (check_etypeok(rmconf, (void *) (intptr_t) etype) == 0)
-		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
-
-	if (approval == NULL)
-		return 0;
-
-	if (etype == ISAKMP_ETYPE_AGG &&
-	    approval->dh_group != rmconf->dh_group)
-		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
-
-	if (checkisakmpsa(rmconf->pcheck_level, approval,
-			  rmconf->proposal) == NULL)
-		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
-
-	return 0;
-}
-
-enum rmconf_match_t {
-	MATCH_NONE		= 0,
-	MATCH_BASIC		= 0x0000001,
-	MATCH_ADDRESS		= 0x0000002,
-	MATCH_SA		= 0x0000004,
-	MATCH_IDENTITY		= 0x0000008,
-	MATCH_AUTH_IDENTITY	= 0x0000010,
-};
-
-static int
-rmconf_match_type(rmsel, rmconf)
-	struct rmconfselector *rmsel;
-	struct remoteconf *rmconf;
-{
-	int ret = MATCH_NONE, tmp;
-
-	/* No match at all: unwanted anonymous */
-	if ((rmsel->flags & GETRMCONF_F_NO_ANONYMOUS) &&
-	    rmconf->remote->sa_family == AF_UNSPEC){
-		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-		     "Not matched: Anonymous conf.\n");
-		return MATCH_NONE;
-	}
-
-	if ((rmsel->flags & GETRMCONF_F_NO_PASSIVE) && rmconf->passive){
-		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-		     "Not matched: passive conf.\n");
-		return MATCH_NONE;
-	}
-
-	ret |= MATCH_BASIC;
-
-	/* Check address */
-	if (rmsel->remote != NULL) {
-		if (rmconf->remote->sa_family != AF_UNSPEC) {
-			if (cmpsaddr(rmsel->remote, rmconf->remote) == CMPSADDR_MISMATCH){
-				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-				     "Not matched: address mismatch.\n");
-				return MATCH_NONE;
-			}
-
-			/* Address matched */
-			ret |= MATCH_ADDRESS;
-		}
-	}
-
-	/* Check etype and approval */
-	if (rmsel->etype != ISAKMP_ETYPE_NONE) {
-		tmp=rmconf_match_etype_and_approval(rmconf, rmsel->etype,
-						    rmsel->approval);
-		if (tmp != 0){
-			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-			     "Not matched: etype (%d)/approval mismatch (%d).\n", rmsel->etype, tmp);
-			return MATCH_NONE;
-		}
-		ret |= MATCH_SA;
-	}
-
-	/* Check identity */
-	if (rmsel->identity != NULL && rmconf->verify_identifier) {
-		if (rmconf_match_identity(rmconf, rmsel->identity) != 0){
-			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-			     "Not matched: identity mismatch.\n");
-			return MATCH_NONE;
-		}
-		ret |= MATCH_IDENTITY;
-	}
-
-	/* Check certificate request */
-	if (rmsel->certificate_request != NULL) {
-		if (oakley_get_certtype(rmsel->certificate_request) !=
-		    oakley_get_certtype(rmconf->mycert)){
-			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-			     "Not matched: cert type mismatch.\n");
-			return MATCH_NONE;
-		}
-
-		if (rmsel->certificate_request->l > 1) {
-			vchar_t *issuer;
-
-			issuer = eay_get_x509asn1issuername(rmconf->mycert);
-			if (rmsel->certificate_request->l - 1 != issuer->l ||
-			    memcmp(rmsel->certificate_request->v + 1,
-				   issuer->v, issuer->l) != 0) {
-				vfree(issuer);
-				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-				     "Not matched: cert issuer mismatch.\n");
-				return MATCH_NONE;
-			}
-			vfree(issuer);
-		} else {
-			if (!rmconf->match_empty_cr){
-				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-				     "Not matched: empty certificate request.\n");
-				return MATCH_NONE;
-			}
-		}
-
-		ret |= MATCH_AUTH_IDENTITY;
-	}
-
-	return ret;
-}
-
-void rmconf_selector_from_ph1(rmsel, iph1)
-	struct rmconfselector *rmsel;
-	struct ph1handle *iph1;
-{
-	memset(rmsel, 0, sizeof(*rmsel));
-	rmsel->flags = 0;
-	rmsel->remote = iph1->remote;
-	rmsel->etype = iph1->etype;
-	rmsel->approval = iph1->approval;
-	rmsel->identity = iph1->id_p;
-	rmsel->certificate_request = iph1->cr_p;
-}
-
-int
-enumrmconf(rmsel, enum_func, enum_arg)
-	struct rmconfselector *rmsel;
-	int (* enum_func)(struct remoteconf *rmconf, void *arg);
-	void *enum_arg;
-{
-	struct remoteconf *p;
-	int ret = 0;
-
-	RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
-		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-		     "Checking remote conf \"%s\" %s.\n", p->name,
-		     p->remote->sa_family == AF_UNSPEC ?
-		     "anonymous" : saddr2str(p->remote));
-
-		if (rmsel != NULL) {
-			if (rmconf_match_type(rmsel, p) == MATCH_NONE){
-				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
-				     "Not matched.\n");
-				continue;
-			}
-		}
-
-		plog(LLV_DEBUG2, LOCATION, NULL,
-		     "enumrmconf: \"%s\" matches.\n", p->name);
-
-		ret = (*enum_func)(p, enum_arg);
-		if (ret)
-			break;
-	}
-
-	return ret;
-}
-
-struct rmconf_find_context {
-	struct rmconfselector sel;
-
-	struct remoteconf *rmconf;
-	int match_type;
-	int num_found;
-};
-
-static int
-rmconf_find(rmconf, ctx)
-	struct remoteconf *rmconf;
-	void *ctx;
-{
-	struct rmconf_find_context *fctx = (struct rmconf_find_context *) ctx;
-	int match_type;
-
-	/* First matching remote conf? */
-	match_type = rmconf_match_type(&fctx->sel, rmconf);
-
-	if (fctx->rmconf != NULL) {
-		/* More ambiguous matches are ignored. */
-		if (match_type < fctx->match_type)
-			return 0;
-
-		if (match_type == fctx->match_type) {
-			/* Ambiguous match */
-			fctx->num_found++;
-			return 0;
-		}
-	}
-
-	/* More exact match found */
-	fctx->match_type = match_type;
-	fctx->num_found = 1;
-	fctx->rmconf = rmconf;
-
-	return 0;
-}
-
 /*
  * search remote configuration.
  * don't use port number to search if its value is either IPSEC_PORT_ANY.
@@ -385,113 +93,79 @@
  * OUT:	NULL:	NG
  *	Other:	remote configuration entry.
  */
-
 struct remoteconf *
-getrmconf(remote, flags)
+getrmconf_strict(remote, allow_anon)
 	struct sockaddr *remote;
-	int flags;
-{
-	struct rmconf_find_context ctx;
-	int n = 0;
-
-	memset(&ctx, 0, sizeof(ctx));
-	ctx.sel.flags = flags;
-	ctx.sel.remote = remote;
-
-	if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) {
-		plog(LLV_ERROR, LOCATION, remote,
-		     "multiple exact configurations.\n");
-		return NULL;
-	}
-
-	if (ctx.rmconf == NULL) {
-		plog(LLV_DEBUG, LOCATION, remote,
-		     "no remote configuration found.\n");
-		return NULL;
-	}
-
-	if (ctx.num_found != 1) {
-		plog(LLV_DEBUG, LOCATION, remote,
-		     "multiple non-exact configurations found.\n");
-		return NULL;
-	}
-
-	plog(LLV_DEBUG, LOCATION, remote,
-	     "configuration \"%s\" selected.\n",
-	     ctx.rmconf->name);
-
-	return ctx.rmconf;
-}
-
-struct remoteconf *
-getrmconf_by_ph1(iph1)
-	struct ph1handle *iph1;
-{
-	struct rmconf_find_context ctx;
-
-	memset(&ctx, 0, sizeof(ctx));
-	rmconf_selector_from_ph1(&ctx.sel, iph1);
-	if (loglevel >= LLV_DEBUG) {
-		char *idstr = NULL;
-
-		if (iph1->id_p != NULL)
-			idstr = ipsecdoi_id2str(iph1->id_p);
-
-		plog(LLV_DEBUG, LOCATION, iph1->remote,
-			"getrmconf_by_ph1: remote %s, identity %s.\n",
-			saddr2str(iph1->remote), idstr ? idstr : "<any>");
-
-		if (idstr)
-			racoon_free(idstr);
-	}
-
-	if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) {
-		plog(LLV_ERROR, LOCATION, iph1->remote,
-		     "multiple exact configurations.\n");
-		return RMCONF_ERR_MULTIPLE;
-	}
-
-	if (ctx.rmconf == NULL) {
-		plog(LLV_DEBUG, LOCATION, iph1->remote,
-		     "no remote configuration found\n");
-		return NULL;
-	}
-
-	if (ctx.num_found != 1) {
-		plog(LLV_DEBUG, LOCATION, iph1->remote,
-		     "multiple non-exact configurations found.\n");
-		return RMCONF_ERR_MULTIPLE;
-	}
-
-	plog(LLV_DEBUG, LOCATION, iph1->remote,
-	     "configuration \"%s\" selected.\n",
-	     ctx.rmconf->name);
-
-	return ctx.rmconf;
-}
-
-struct remoteconf *
-getrmconf_by_name(name)
-	const char *name;
+	int allow_anon;
 {
 	struct remoteconf *p;
+	struct remoteconf *anon = NULL;
+	int withport;
+	char buf[NI_MAXHOST + NI_MAXSERV + 10];
+	char addr[NI_MAXHOST], port[NI_MAXSERV];
 
-	plog(LLV_DEBUG, LOCATION, NULL,
-	     "getrmconf_by_name: remote \"%s\".\n",
-	     name);
+	withport = 0;
 
-	RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
-		if (p->name == NULL)
-			continue;
+#ifndef ENABLE_NATT
+	/* 
+	 * We never have ports set in our remote configurations, but when
+	 * NAT-T is enabled, the kernel can have policies with ports and
+	 * send us an acquire message for a destination that has a port set.
+	 * If we do this port check here, we don't find the remote config.
+	 *
+	 * In an ideal world, we would be able to have remote conf with
+	 * port, and the port could be a wildcard. That test could be used.
+	 */
+	if (remote->sa_family != AF_UNSPEC &&
+	    extract_port(remote) != IPSEC_PORT_ANY)
+		withport = 1;
+#endif /* ENABLE_NATT */
 
-		if (strcmp(name, p->name) == 0)
-			return p;
+	if (remote->sa_family == AF_UNSPEC)
+		snprintf (buf, sizeof(buf), "%s", "anonymous");
+	else {
+		GETNAMEINFO(remote, addr, port);
+		snprintf(buf, sizeof(buf), "%s%s%s%s", addr,
+			withport ? "[" : "",
+			withport ? port : "",
+			withport ? "]" : "");
 	}
 
+	TAILQ_FOREACH(p, &rmtree, chain) {
+		if ((remote->sa_family == AF_UNSPEC
+		     && remote->sa_family == p->remote->sa_family)
+		 || (!withport && cmpsaddrwop(remote, p->remote) == 0)
+		 || (withport && cmpsaddrstrict(remote, p->remote) == 0)) {
+			plog(LLV_DEBUG, LOCATION, NULL,
+				"configuration found for %s.\n", buf);
+			return p;
+		}
+
+		/* save the pointer to the anonymous configuration */
+		if (p->remote->sa_family == AF_UNSPEC)
+			anon = p;
+	}
+
+	if (allow_anon && anon != NULL) {
+		plog(LLV_DEBUG, LOCATION, NULL,
+			"anonymous configuration selected for %s.\n", buf);
+		return anon;
+	}
+
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"no remote configuration found.\n");
+
 	return NULL;
 }
 
 struct remoteconf *
+getrmconf(remote)
+	struct sockaddr *remote;
+{
+	return getrmconf_strict(remote, 1);
+}
+
+struct remoteconf *
 newrmconf()
 {
 	struct remoteconf *new;
@@ -517,14 +191,19 @@
 	new->pcheck_level = PROP_CHECK_STRICT;
 	new->verify_identifier = FALSE;
 	new->verify_cert = TRUE;
+	new->getcert_method = ISAKMP_GETCERT_PAYLOAD;
+	new->getcacert_method = ISAKMP_GETCERT_LOCALFILE;
+	new->cacerttype = ISAKMP_CERT_X509SIGN;
+	new->certtype = ISAKMP_CERT_NONE;
 	new->cacertfile = NULL;
 	new->send_cert = TRUE;
 	new->send_cr = TRUE;
-	new->match_empty_cr = FALSE;
 	new->support_proxy = FALSE;
 	for (i = 0; i <= SCRIPT_MAX; i++)
 		new->script[i] = NULL;
 	new->gen_policy = FALSE;
+	new->retry_counter = lcconf->retry_counter;
+	new->retry_interval = lcconf->retry_interval;
 	new->nat_traversal = FALSE;
 	new->rsa_private = genlist_init();
 	new->rsa_public = genlist_init();
@@ -536,20 +215,33 @@
 	new->dpd_retry = 5;
 	new->dpd_maxfails = 5;
 
-	new->rekey = REKEY_ON;
-
 	new->weak_phase1_check = 0;
 
 #ifdef ENABLE_HYBRID
 	new->xauth = NULL;
 #endif
 
-	new->lifetime = oakley_get_defaultlifetime();
-
 	return new;
 }
 
-#ifndef ANDROID_PATCHED
+struct remoteconf *
+copyrmconf(remote)
+	struct sockaddr *remote;
+{
+	struct remoteconf *new, *old;
+
+	old = getrmconf_strict (remote, 0);
+	if (old == NULL) {
+		plog (LLV_ERROR, LOCATION, NULL,
+		      "Remote configuration for '%s' not found!\n",
+		      saddr2str (remote));
+		return NULL;
+	}
+
+	new = duprmconf (old);
+
+	return new;
+}
 
 void *
 dupidvl(entry, arg)
@@ -572,147 +264,29 @@
 	return NULL;
 }
 
-void *
-duprsa(entry, arg)
-	void *entry;
-	void *arg;
-{
-	struct rsa_key *new;
-
-	new = rsa_key_dup((struct rsa_key *)entry);
-	if (new == NULL)
-		return (void *) -1;
-	genlist_append(arg, new);
-
-	/* keep genlist_foreach going */
-	return NULL;
-}
-
-/* Creates shallow copy of a remote config. Used for "inherit" keyword. */
 struct remoteconf *
-duprmconf_shallow (rmconf)
+duprmconf (rmconf)
 	struct remoteconf *rmconf;
 {
 	struct remoteconf *new;
-	struct proposalspec *prspec;
 
 	new = racoon_calloc(1, sizeof(*new));
 	if (new == NULL)
 		return NULL;
-
-	memcpy(new, rmconf, sizeof(*new));
-	new->name = NULL;
-	new->inherited_from = rmconf;
-
-	new->proposal = NULL; /* will be filled by set_isakmp_proposal() */
+	memcpy (new, rmconf, sizeof (*new));
+	// FIXME: We should duplicate the proposal as well.
+	// This is now handled in the cfparse.y
+	// new->proposal = ...;
+	
+	/* duplicate dynamic structures */
+	if (new->etypes)
+		new->etypes=dupetypes(new->etypes);
+	new->idvl_p = genlist_init();
+	genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
 
 	return new;
 }
 
-/* Copies pointer structures of an inherited remote config. 
- * Used by "inherit" mechanism in a two step copy method, necessary to
- * prevent both double free() and memory leak during config reload.
- */
-int
-duprmconf_finish (new)
-	struct remoteconf *new;
-{
-	struct remoteconf *rmconf;
-	int i;
-
-	if (new->inherited_from == NULL)
-		return 0; /* nothing todo, no inheritance */
-
-	rmconf = new->inherited_from;
-
-	/* duplicate dynamic structures unless value overridden */
-	if (new->etypes != NULL && new->etypes == rmconf->etypes)
-		new->etypes = dupetypes(new->etypes);
-	if (new->idvl_p == rmconf->idvl_p) {
-		new->idvl_p = genlist_init();
-		genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
-	}
-
-	if (new->rsa_private == rmconf->rsa_private) {
-		new->rsa_private = genlist_init();
-		genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private);
-	}
-	if (new->rsa_public == rmconf->rsa_public) {
-		new->rsa_public = genlist_init();
-		genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public);
-	}
-	if (new->remote != NULL && new->remote == rmconf->remote) {
-		new->remote = racoon_malloc(sizeof(*new->remote));
-		if (new->remote == NULL) {
-			plog(LLV_ERROR, LOCATION, NULL, 
-			    "duprmconf_finish: malloc failed (remote)\n");
-			exit(1);
-		}
-		memcpy(new->remote, rmconf->remote, sizeof(*new->remote));
-	}
-	if (new->spspec != NULL && new->spspec == rmconf->spspec) {
-		dupspspec_list(new, rmconf);
-	}
-
-	/* proposal has been deep copied already from spspec's, see
-	 * cfparse.y:set_isakmp_proposal, which in turn calls
-	 * cfparse.y:expand_isakmpspec where the copying happens.
-	 */
-
-#ifdef ENABLE_HYBRID
-	if (new->xauth != NULL && new->xauth == rmconf->xauth) {
-		new->xauth = xauth_rmconf_dup(new->xauth);
-		if (new->xauth == NULL)
-			exit(1);
-	}
-#endif
-
-        /* duplicate strings unless value overridden */ 
-	if (new->mycertfile != NULL && new->mycertfile == rmconf->mycertfile) { 
-		new->mycertfile = racoon_strdup(new->mycertfile); 
-		STRDUP_FATAL(new->mycertfile); 
-	} 
-	if (new->myprivfile != NULL && new->myprivfile == rmconf->myprivfile) { 
-		new->myprivfile = racoon_strdup(new->myprivfile); 
-		STRDUP_FATAL(new->myprivfile); 
-	} 
-	if (new->peerscertfile != NULL && new->peerscertfile == rmconf->peerscertfile) { 
-		new->peerscertfile = racoon_strdup(new->peerscertfile); 
-		STRDUP_FATAL(new->peerscertfile); 
-	} 
-	if (new->cacertfile != NULL && new->cacertfile == rmconf->cacertfile) { 
-		new->cacertfile = racoon_strdup(new->cacertfile); 
-		STRDUP_FATAL(new->cacertfile); 
-	} 
-	if (new->idv != NULL && new->idv == rmconf->idv) {
-		new->idv = vdup(new->idv); 
-		STRDUP_FATAL(new->idv); 
-	}
-	if (new->key != NULL && new->key == rmconf->key) {
-		new->key = vdup(new->key); 
-		STRDUP_FATAL(new->key); 
-	}
-	if (new->mycert != NULL && new->mycert == rmconf->mycert) {
-		new->mycert = vdup(new->mycert);
-		STRDUP_FATAL(new->mycert); 
-	}
-	if (new->peerscert != NULL && new->peerscert == rmconf->peerscert) {
-		new->peerscert = vdup(new->peerscert);
-		STRDUP_FATAL(new->peerscert); 
-	}
-	if (new->cacert != NULL && new->cacert == rmconf->cacert) {
-		new->cacert = vdup(new->cacert);
-		STRDUP_FATAL(new->cacert); 
-	}
-	for (i = 0; i <= SCRIPT_MAX; i++)
-		if (new->script[i] != NULL && new->script[i] == rmconf->script[i]) {
-			new->script[i] = vdup(new->script[i]);
-			STRDUP_FATAL(new->script[i]);
-		}
-
-	return 0;
-}
-
 static void
 idspec_free(void *data)
 {
@@ -724,8 +298,6 @@
 delrmconf(rmconf)
 	struct remoteconf *rmconf;
 {
-	int i;
-
 #ifdef ENABLE_HYBRID
 	if (rmconf->xauth)
 		xauth_rmconf_delete(&rmconf->xauth);
@@ -734,55 +306,15 @@
 		deletypes(rmconf->etypes);
 		rmconf->etypes=NULL;
 	}
-	if (rmconf->idv)
-		vfree(rmconf->idv);
-	if (rmconf->key)
-		vfree(rmconf->key);
 	if (rmconf->idvl_p)
 		genlist_free(rmconf->idvl_p, idspec_free);
 	if (rmconf->dhgrp)
 		oakley_dhgrp_free(rmconf->dhgrp);
 	if (rmconf->proposal)
 		delisakmpsa(rmconf->proposal);
-	flushspspec(rmconf);
-	if (rmconf->mycert)
-		vfree(rmconf->mycert);
-	if (rmconf->mycertfile)
-		racoon_free(rmconf->mycertfile);
-	if (rmconf->myprivfile)
-		racoon_free(rmconf->myprivfile);
-	if (rmconf->peerscert)
-		vfree(rmconf->peerscert);
-	if (rmconf->peerscertfile)
-		racoon_free(rmconf->peerscertfile);
-	if (rmconf->cacert)
-		vfree(rmconf->cacert);
-	if (rmconf->cacertfile)
-		racoon_free(rmconf->cacertfile);
-	if (rmconf->rsa_private)
-		genlist_free(rmconf->rsa_private, rsa_key_free);
-	if (rmconf->rsa_public)
-		genlist_free(rmconf->rsa_public, rsa_key_free);
-	if (rmconf->name)
-		racoon_free(rmconf->name);
-	if (rmconf->remote)
-		racoon_free(rmconf->remote);
-	for (i = 0; i <= SCRIPT_MAX; i++)
-		if (rmconf->script[i])
-			vfree(rmconf->script[i]);
-
 	racoon_free(rmconf);
 }
 
-#else
-
-void delrmconf(struct remoteconf *rmconf)
-{
-        exit(1);
-}
-
-#endif
-
 void
 delisakmpsa(sa)
 	struct isakmpsa *sa;
@@ -804,11 +336,11 @@
 {
 	struct etypes *new;
 
-	if (!orig)
+	if (!orig) 
 		return NULL;
 
 	new = racoon_malloc(sizeof(struct etypes));
-	if (new == NULL)
+	if (new == NULL) 
 		return NULL;
 
 	new->type = orig->type;
@@ -836,14 +368,6 @@
 insrmconf(new)
 	struct remoteconf *new;
 {
-	if (new->name == NULL) {
-		new->name = racoon_strdup(saddr2str(new->remote));
-	}
-	if (new->remote == NULL) {
-		new->remote = newsaddr(sizeof(struct sockaddr));
-		new->remote->sa_family = AF_UNSPEC;
-	}
-
 	TAILQ_INSERT_HEAD(&rmtree, new, chain);
 }
 
@@ -873,17 +397,15 @@
 }
 
 void
-rmconf_start_reload()
+save_rmconf()
 {
 	rmtree_save=rmtree;
 	initrmconf();
 }
 
 void
-rmconf_finish_reload()
+save_rmconf_flush()
 {
-	remoteconf_tailq_head_t rmtree_tmp;
-
 	rmtree_tmp=rmtree;
 	rmtree=rmtree_save;
 	flushrmconf();
@@ -894,22 +416,19 @@
 
 
 /* check exchange type to be acceptable */
-int
-check_etypeok(rmconf, ctx)
+struct etypes *
+check_etypeok(rmconf, etype)
 	struct remoteconf *rmconf;
-	void *ctx;
+	u_int8_t etype;
 {
-	u_int8_t etype = (u_int8_t) (intptr_t) ctx;
 	struct etypes *e;
 
 	for (e = rmconf->etypes; e != NULL; e = e->next) {
 		if (e->type == etype)
-			return 1;
-		plog(LLV_DEBUG2, LOCATION, NULL,
-		     "Etype mismatch: got %d, expected %d.\n", e->type, etype);
+			break;
 	}
 
-	return 0;
+	return e;
 }
 
 /*%%%*/
@@ -929,6 +448,7 @@
 	new->vendorid = VENDORID_UNKNOWN;
 
 	new->next = NULL;
+	new->rmconf = NULL;
 #ifdef HAVE_GSSAPI
 	new->gssid = NULL;
 #endif
@@ -946,6 +466,8 @@
 {
 	struct isakmpsa *p;
 
+	new->rmconf = rmconf;
+
 	if (rmconf->proposal == NULL) {
 		rmconf->proposal = new;
 		return;
@@ -954,6 +476,21 @@
 	for (p = rmconf->proposal; p->next != NULL; p = p->next)
 		;
 	p->next = new;
+
+	return;
+}
+
+struct remoteconf *
+foreachrmconf(rmconf_func_t rmconf_func, void *data)
+{
+  struct remoteconf *p, *ret = NULL;
+  RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
+    ret = (*rmconf_func)(p, data);
+    if (ret)
+      break;
+  }
+
+  return ret;
 }
 
 static void *
@@ -970,7 +507,7 @@
 	return NULL;
 }
 
-static int
+static struct remoteconf *
 dump_rmconf_single (struct remoteconf *p, void *data)
 {
 	struct etypes *etype = p->etypes;
@@ -978,11 +515,10 @@
 	char buf[1024], *pbuf;
 
 	pbuf = buf;
-
-	pbuf += sprintf(pbuf, "remote \"%s\"", p->name);
+	pbuf += sprintf(pbuf, "remote %s", saddr2str(p->remote));
 	if (p->inherited_from)
-		pbuf += sprintf(pbuf, " inherit \"%s\"",
-				p->inherited_from->name);
+		pbuf += sprintf(pbuf, " inherit %s",
+				saddr2str(p->inherited_from->remote));
 	plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf);
 	pbuf = buf;
 	pbuf += sprintf(pbuf, "\texchange_type ");
@@ -997,30 +533,23 @@
 	pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype));
 	if (p->idvtype == IDTYPE_ASN1DN) {
 		plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
-		plog(LLV_INFO, LOCATION, NULL,
-		     "\tcertificate_type %s \"%s\" \"%s\";\n",
-		     oakley_get_certtype(p->mycert) == ISAKMP_CERT_X509SIGN
-		       ? "x509" : "*UNKNOWN*",
-		     p->mycertfile, p->myprivfile);
-
-		switch (oakley_get_certtype(p->peerscert)) {
-		case ISAKMP_CERT_NONE:
-			plog(LLV_INFO, LOCATION, NULL,
-			     "\t/* peers certificate from payload */\n");
+		plog(LLV_INFO, LOCATION, NULL, "\tcertificate_type %s \"%s\" \"%s\";\n",
+			p->certtype == ISAKMP_CERT_X509SIGN ? "x509" : "*UNKNOWN*",
+			p->mycertfile, p->myprivfile);
+		switch (p->getcert_method) {
+		  case 0:
+		  	break;
+		  case ISAKMP_GETCERT_PAYLOAD:
+			plog(LLV_INFO, LOCATION, NULL, "\t/* peers certificate from payload */\n");
 			break;
-		case ISAKMP_CERT_X509SIGN:
-			plog(LLV_INFO, LOCATION, NULL,
-			     "\tpeers_certfile \"%s\";\n", p->peerscertfile);
+		  case ISAKMP_GETCERT_LOCALFILE:
+			plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile \"%s\";\n", p->peerscertfile);
 			break;
-		case ISAKMP_CERT_DNS:
-			plog(LLV_INFO, LOCATION, NULL,
-			     "\tpeers_certfile dnssec;\n");
+		  case ISAKMP_GETCERT_DNS:
+			plog(LLV_INFO, LOCATION, NULL, "\tpeer_certfile dnssec;\n");
 			break;
-		default:
-			plog(LLV_INFO, LOCATION, NULL,
-			     "\tpeers_certfile *UNKNOWN* (%d)\n",
-			     oakley_get_certtype(p->peerscert));
-			break;
+		  default:
+			plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile *UNKNOWN* (%d)\n", p->getcert_method);
 		}
 	}
 	else {
@@ -1030,14 +559,10 @@
 		genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL);
 	}
 
-	plog(LLV_INFO, LOCATION, NULL, "\trekey %s;\n",
-		p->rekey == REKEY_FORCE ? "force" : s_switch (p->rekey));
 	plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n",
 		s_switch (p->send_cert));
 	plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n",
 		s_switch (p->send_cr));
-	plog(LLV_INFO, LOCATION, NULL, "\tmatch_empty_cr %s;\n",
-		s_switch (p->match_empty_cr));
 	plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n",
 		s_switch (p->verify_cert));
 	plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n",
@@ -1063,8 +588,9 @@
 	while (prop) {
 		plog(LLV_INFO, LOCATION, NULL, "\n");
 		plog(LLV_INFO, LOCATION, NULL,
-			"\t/* prop_no=%d, trns_no=%d */\n",
-			prop->prop_no, prop->trns_no);
+			"\t/* prop_no=%d, trns_no=%d, rmconf=%s */\n",
+			prop->prop_no, prop->trns_no,
+			saddr2str(prop->rmconf->remote));
 		plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n");
 		plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n",
 			(long)prop->lifetime);
@@ -1072,11 +598,11 @@
 			prop->lifebyte);
 		plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n",
 			alg_oakley_dhdef_name(prop->dh_group));
-		plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n",
+		plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n", 
 			alg_oakley_encdef_name(prop->enctype));
-		plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n",
+		plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n", 
 			alg_oakley_hashdef_name(prop->hashtype));
-		plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n",
+		plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n", 
 			alg_oakley_authdef_name(prop->authmethod));
 		plog(LLV_INFO, LOCATION, NULL, "\t}\n");
 		prop = prop->next;
@@ -1084,13 +610,13 @@
 	plog(LLV_INFO, LOCATION, NULL, "}\n");
 	plog(LLV_INFO, LOCATION, NULL, "\n");
 
-	return 0;
+	return NULL;
 }
 
 void
 dumprmconf()
 {
-	enumrmconf(NULL, dump_rmconf_single, NULL);
+	foreachrmconf (dump_rmconf_single, NULL);
 }
 
 struct idspec *
@@ -1145,115 +671,25 @@
 struct isakmpsa *
 dupisakmpsa(struct isakmpsa *sa)
 {
-	struct isakmpsa *res = NULL;
+	struct isakmpsa *res=NULL;
 
 	if(sa == NULL)
 		return NULL;
 
-	res = newisakmpsa();
+	res=newisakmpsa();
 	if(res == NULL)
 		return NULL;
 
-	*res = *sa;
+	*res=*sa;
 #ifdef HAVE_GSSAPI
-	if (sa->gssid != NULL)
-		res->gssid = vdup(sa->gssid);
+	/* XXX gssid
+	 */
 #endif
-	res->next = NULL;
+	res->next=NULL;
 
 	if(sa->dhgrp != NULL)
-		oakley_setdhgroup(sa->dh_group, &res->dhgrp);
+		oakley_setdhgroup (sa->dh_group, &(res->dhgrp));
 
 	return res;
 
 }
-
-#ifdef ENABLE_HYBRID
-int
-isakmpsa_switch_authmethod(authmethod)
-	int authmethod;
-{
-	switch(authmethod) {
-	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
-		break;
-	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I;
-		break;
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
-		break;
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
-		break;
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
-		break;
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I;
-		break;
-	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
-		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I;
-		break;
-	default:
-		break;
-	}
-
-	return authmethod;
-}
-#endif
-
-/*
- * Given a proposed ISAKMP SA, and a list of acceptable
- * ISAKMP SAs, it compares using pcheck_level policy and
- * returns first match (if any).
- */
-struct isakmpsa *
-checkisakmpsa(pcheck_level, proposal, acceptable)
-	int pcheck_level;
-	struct isakmpsa *proposal, *acceptable;
-{
-	struct isakmpsa *p;
-
-	for (p = acceptable; p != NULL; p = p->next){
-		plog(LLV_DEBUG2, LOCATION, NULL,
-		     "checkisakmpsa:\nauthmethod: %d / %d\n",
-		     isakmpsa_switch_authmethod(proposal->authmethod), isakmpsa_switch_authmethod(p->authmethod));
-		if (isakmpsa_switch_authmethod(proposal->authmethod) != isakmpsa_switch_authmethod(p->authmethod) ||
-		    proposal->enctype != p->enctype ||
-                    proposal->dh_group != p->dh_group ||
-		    proposal->hashtype != p->hashtype)
-			continue;
-
-		switch (pcheck_level) {
-		case PROP_CHECK_OBEY:
-			break;
-
-		case PROP_CHECK_CLAIM:
-		case PROP_CHECK_STRICT:
-			if (proposal->encklen < p->encklen ||
-#if 0
-			    proposal->lifebyte > p->lifebyte ||
-#endif
-			    proposal->lifetime > p->lifetime)
-				continue;
-			break;
-
-		case PROP_CHECK_EXACT:
-			if (proposal->encklen != p->encklen ||
-#if 0
-                            proposal->lifebyte != p->lifebyte ||
-#endif
-			    proposal->lifetime != p->lifetime)
-				continue;
-			break;
-
-		default:
-			continue;
-		}
-
-		return p;
-	}
-
-	return NULL;
-}
diff --git a/src/racoon/remoteconf.h b/src/racoon/remoteconf.h
index 3ebe004..ca5945e 100644
--- a/src/racoon/remoteconf.h
+++ b/src/racoon/remoteconf.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: remoteconf.h,v 1.16 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: remoteconf.h,v 1.7 2006/10/03 08:01:56 vanhu Exp $	*/
 
 /* Id: remoteconf.h,v 1.26 2006/05/06 15:52:44 manubsd Exp */
 
@@ -43,14 +43,95 @@
 #include "isakmp_xauth.h"
 #endif
 
-struct ph1handle;
-struct secprotospec;
+struct proposalspec;
 
 struct etypes {
 	int type;
 	struct etypes *next;
 };
 
+/* Script hooks */
+#define SCRIPT_PHASE1_UP	0
+#define SCRIPT_PHASE1_DOWN	1
+#define SCRIPT_MAX		1
+extern char *script_names[SCRIPT_MAX + 1];
+
+struct remoteconf {
+	struct sockaddr *remote;	/* remote IP address */
+					/* if family is AF_UNSPEC, that is
+					 * for anonymous configuration. */
+
+	struct etypes *etypes;		/* exchange type list. the head
+					 * is a type to be sent first. */
+	int doitype;			/* doi type */
+	int sittype;			/* situation type */
+
+	int idvtype;			/* my identifier type */
+	vchar_t *idv;			/* my identifier */
+	vchar_t *key;			/* my pre-shared key */
+	struct genlist *idvl_p;         /* peer's identifiers list */
+
+	int certtype;			/* certificate type if need */
+	char *mycertfile;		/* file name of my certificate */
+	char *myprivfile;		/* file name of my private key file */
+	char *peerscertfile;		/* file name of peer's certifcate */
+	int getcert_method;		/* the way to get peer's certificate */
+	int cacerttype;			/* CA type is needed */
+	char *cacertfile;		/* file name of CA */
+	int getcacert_method;		/* the way to get the CA */
+	int send_cert;			/* send to CERT or not */
+	int send_cr;			/* send to CR or not */
+	int verify_cert;		/* verify a CERT strictly */
+	int verify_identifier;		/* vefify the peer's identifier */
+	int nonce_size;			/* the number of bytes of nonce */
+	int passive;			/* never initiate */
+	int ike_frag;			/* IKE fragmentation */
+	int esp_frag;			/* ESP fragmentation */
+	int mode_cfg;			/* Gets config through mode config */
+	int support_proxy;		/* support mip6/proxy */
+#define GENERATE_POLICY_NONE   0
+#define GENERATE_POLICY_REQUIRE        1
+#define GENERATE_POLICY_UNIQUE 2
+	int gen_policy;			/* generate policy if no policy found */
+	int ini_contact;		/* initial contact */
+	int pcheck_level;		/* level of propocl checking */
+	int nat_traversal;		/* NAT-Traversal */
+	vchar_t *script[SCRIPT_MAX + 1];/* script hooks paths */
+	int dh_group;			/* use it when only aggressive mode */
+	struct dhgroup *dhgrp;		/* use it when only aggressive mode */
+					/* above two can't be defined by user*/
+
+	int retry_counter;		/* times to retry. */
+	int retry_interval;		/* interval each retry. */
+				/* above 2 values are copied from localconf. */
+
+	int dpd;				/* Negociate DPD support ? */
+	int dpd_retry;			/* in seconds */
+	int dpd_interval;		/* in seconds */
+	int dpd_maxfails; 
+
+	int ph1id; /* ph1id to be matched with sainfo sections */
+
+	int weak_phase1_check;		/* act on unencrypted deletions ? */
+
+	struct isakmpsa *proposal;	/* proposal list */
+	struct remoteconf *inherited_from;	/* the original rmconf 
+						   from which this one 
+						   was inherited */
+	struct proposalspec *prhead;
+
+	struct genlist	*rsa_private,	/* lists of PlainRSA keys to use */
+			*rsa_public;
+
+#ifdef ENABLE_HYBRID
+	struct xauth_rmconf *xauth;
+#endif
+
+	TAILQ_ENTRY(remoteconf) chain;	/* next remote conf */
+};
+
+struct dhgroup;
+
 /* ISAKMP SA specification */
 struct isakmpsa {
 	int prop_no;
@@ -69,170 +150,42 @@
 	struct dhgroup *dhgrp;		/* don't use it if aggressive mode */
 
 	struct isakmpsa *next;		/* next transform */
+	struct remoteconf *rmconf;	/* backpointer to remoteconf */
 };
 
-/* Certificate information */
-struct rmconf_cert {
-	vchar_t *data;			/* certificate payload */
-	char *filename;			/* name of local file */
-};
-
-/* Script hooks */
-#define SCRIPT_PHASE1_UP	0
-#define SCRIPT_PHASE1_DOWN	1
-#define SCRIPT_PHASE1_DEAD	2
-#define SCRIPT_MAX		2
-extern char *script_names[SCRIPT_MAX + 1];
-
-struct remoteconf {
-	char *name;			/* remote configuration name */
-	struct sockaddr *remote;	/* remote IP address */
-					/* if family is AF_UNSPEC, that is
-					 * for anonymous configuration. */
-
-	struct etypes *etypes;		/* exchange type list. the head
-					 * is a type to be sent first. */
-	int doitype;			/* doi type */
-	int sittype;			/* situation type */
-
-	int idvtype;			/* my identifier type */
-	vchar_t *idv;			/* my identifier */
-	vchar_t *key;			/* my pre-shared key */
-	struct genlist *idvl_p;         /* peer's identifiers list */
-
-	char *myprivfile;		/* file name of my private key file */
-	char *mycertfile;		/* file name of my certificate */
-	vchar_t *mycert;		/* my certificate */
-	char *peerscertfile;		/* file name of peer's certifcate */
-	vchar_t *peerscert;		/* peer's certificate */
-	char *cacertfile;		/* file name of CA */
-	vchar_t *cacert;		/* CA certificate */
-
-	int send_cert;			/* send to CERT or not */
-	int send_cr;			/* send to CR or not */
-	int match_empty_cr;		/* does this match if CR is empty */
-	int verify_cert;		/* verify a CERT strictly */
-	int verify_identifier;		/* vefify the peer's identifier */
-	int nonce_size;			/* the number of bytes of nonce */
-	int passive;			/* never initiate */
-	int ike_frag;			/* IKE fragmentation */
-	int esp_frag;			/* ESP fragmentation */
-	int mode_cfg;			/* Gets config through mode config */
-	int support_proxy;		/* support mip6/proxy */
-#define GENERATE_POLICY_NONE	0
-#define GENERATE_POLICY_REQUIRE	1
-#define GENERATE_POLICY_UNIQUE	2
-	int gen_policy;			/* generate policy if no policy found */
-	int ini_contact;		/* initial contact */
-	int pcheck_level;		/* level of propocl checking */
-	int nat_traversal;		/* NAT-Traversal */
-	vchar_t *script[SCRIPT_MAX + 1];/* script hooks paths */
-	int dh_group;			/* use it when only aggressive mode */
-	struct dhgroup *dhgrp;		/* use it when only aggressive mode */
-					/* above two can't be defined by user*/
-
-	int dpd;				/* Negociate DPD support ? */
-	int dpd_retry;			/* in seconds */
-	int dpd_interval;		/* in seconds */
-	int dpd_maxfails;
-
-	int rekey;			/* rekey ph1 when active ph2s? */
-#define REKEY_OFF		FALSE
-#define REKEY_ON		TRUE
-#define REKEY_FORCE		2
-
-	uint32_t ph1id; /* ph1id to be matched with sainfo sections */
-
-	int weak_phase1_check;		/* act on unencrypted deletions ? */
-
-	struct isakmpsa *proposal;	/* proposal list */
-	struct remoteconf *inherited_from;	/* the original rmconf 
-						   from which this one 
-						   was inherited */
-
-	time_t lifetime;		/* for isakmp/ipsec */
-	int lifebyte;			/* for isakmp/ipsec */
-	struct secprotospec *spspec;	/* the head is always current spec. */
-
-	struct genlist	*rsa_private,	/* lists of PlainRSA keys to use */
-			*rsa_public;
-
-#ifdef ENABLE_HYBRID
-	struct xauth_rmconf *xauth;
-#endif
-
-	TAILQ_ENTRY(remoteconf) chain;	/* next remote conf */
-};
-
-#define RMCONF_NONCE_SIZE(rmconf) \
-	(rmconf != NULL ? rmconf->nonce_size : DEFAULT_NONCE_SIZE)
-
-struct dhgroup;
-
 struct idspec {
 	int idtype;                     /* identifier type */
 	vchar_t *id;                    /* identifier */
 };
 
-struct rmconfselector {
-	int flags;
-	struct sockaddr *remote;
-	int etype;
-	struct isakmpsa *approval;
-	vchar_t *identity;
-	vchar_t *certificate_request;
-};
+typedef struct remoteconf * (rmconf_func_t)(struct remoteconf *rmconf, void *data);
 
-extern void rmconf_selector_from_ph1 __P((struct rmconfselector *rmsel,
-					  struct ph1handle *iph1));
-extern int enumrmconf __P((struct rmconfselector *rmsel,
-			   int (* enum_func)(struct remoteconf *rmconf, void *arg),
-			   void *enum_arg));
-
-#define GETRMCONF_F_NO_ANONYMOUS	0x0001
-#define GETRMCONF_F_NO_PASSIVE		0x0002
-
-#define RMCONF_ERR_MULTIPLE		((struct remoteconf *) -1)
-
-extern int rmconf_match_identity __P((struct remoteconf *rmconf,
-				      vchar_t *id_p));
-extern struct remoteconf *getrmconf __P((struct sockaddr *remote, int flags));
-extern struct remoteconf *getrmconf_by_ph1 __P((struct ph1handle *iph1));
-extern struct remoteconf *getrmconf_by_name __P((const char *name));
-
+extern struct remoteconf *getrmconf __P((struct sockaddr *));
+extern struct remoteconf *getrmconf_strict
+	__P((struct sockaddr *remote, int allow_anon));
+extern struct remoteconf *copyrmconf __P((struct sockaddr *));
 extern struct remoteconf *newrmconf __P((void));
-extern struct remoteconf *duprmconf_shallow __P((struct remoteconf *));
-extern int duprmconf_finish __P((struct remoteconf *));
+extern struct remoteconf *duprmconf __P((struct remoteconf *));
 extern void delrmconf __P((struct remoteconf *));
+extern void delisakmpsa __P((struct isakmpsa *));
 extern void deletypes __P((struct etypes *));
 extern struct etypes * dupetypes __P((struct etypes *));
 extern void insrmconf __P((struct remoteconf *));
 extern void remrmconf __P((struct remoteconf *));
 extern void flushrmconf __P((void));
-extern void dupspspec_list __P((struct remoteconf *, struct remoteconf *));
-extern void flushspspec __P((struct remoteconf *));
 extern void initrmconf __P((void));
-extern void rmconf_start_reload __P((void));
-extern void rmconf_finish_reload __P((void));
+extern void save_rmconf __P((void));
+extern void save_rmconf_flush __P((void));
 
-extern int check_etypeok __P((struct remoteconf *, void *));
+extern struct etypes *check_etypeok
+	__P((struct remoteconf *, u_int8_t));
+extern struct remoteconf *foreachrmconf __P((rmconf_func_t rmconf_func,
+					     void *data));
 
 extern struct isakmpsa *newisakmpsa __P((void));
 extern struct isakmpsa *dupisakmpsa __P((struct isakmpsa *));
-extern void delisakmpsa __P((struct isakmpsa *));
-extern void insisakmpsa __P((struct isakmpsa *, struct remoteconf *));
-#ifdef ENABLE_HYBRID
-extern int isakmpsa_switch_authmethod __P((int authmethod));
-#else
-static inline int isakmpsa_switch_authmethod(int authmethod)
-{
-	return authmethod;
-}
-#endif
-extern struct isakmpsa * checkisakmpsa __P((int pcheck,
-					    struct isakmpsa *proposal,
-					    struct isakmpsa *acceptable));
 
+extern void insisakmpsa __P((struct isakmpsa *, struct remoteconf *));
 
 extern void dumprmconf __P((void));
 
diff --git a/src/racoon/rsalist.c b/src/racoon/rsalist.c
index f152c82..850aa4c 100644
--- a/src/racoon/rsalist.c
+++ b/src/racoon/rsalist.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: rsalist.c,v 1.6 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: rsalist.c,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: rsalist.c,v 1.3 2004/11/08 12:04:23 ludvigm Exp */
 
@@ -88,65 +88,6 @@
 	return 0;
 }
 
-struct rsa_key *
-rsa_key_dup(struct rsa_key *key)
-{
-	struct rsa_key *new;
-
-	new = calloc(sizeof(struct rsa_key), 1);
-	if (new == NULL)
-		return NULL;
-
-	if (key->rsa) {
-		new->rsa = key->rsa->d != NULL ? RSAPrivateKey_dup(key->rsa) : RSAPublicKey_dup(key->rsa);
-		if (new->rsa == NULL)
-			goto dup_error;
-	}
-
-	if (key->src) {
-		new->src = malloc(sizeof(*new->src));
-		if (new->src == NULL)
-			goto dup_error;
-		memcpy(new->src, key->src, sizeof(*new->src));
-	}	
-	if (key->dst) {
-		new->dst = malloc(sizeof(*new->dst));
-		if (new->dst == NULL)
-			goto dup_error;
-		memcpy(new->dst, key->dst, sizeof(*new->dst));
-	}
-
-	return new;
-
-dup_error:
-	if (new->rsa != NULL)
-		RSA_free(new->rsa);
-	if (new->dst != NULL)
-		free(new->dst);
-	if (new->src != NULL)
-		free(new->src);
-
-	free(new);
-	return NULL;
-}
-
-void
-rsa_key_free(void *data)
-{
-	struct rsa_key *rsa_key;
-
-	
-	rsa_key = (struct rsa_key *)data;
-	if (rsa_key->src)
-		free(rsa_key->src);
-	if (rsa_key->dst)
-		free(rsa_key->dst);
-	if (rsa_key->rsa)
-		RSA_free(rsa_key->rsa);
-
-	free(rsa_key);
-}
-
 static void *
 rsa_key_dump_one(void *entry, void *arg)
 {
diff --git a/src/racoon/rsalist.h b/src/racoon/rsalist.h
index bc6a8d9..911670f 100644
--- a/src/racoon/rsalist.h
+++ b/src/racoon/rsalist.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: rsalist.h,v 1.6 2011/03/14 15:50:36 vanhu Exp $	*/
+/*	$NetBSD: rsalist.h,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: rsalist.h,v 1.2 2004/07/12 20:43:51 ludvigm Exp */
 /*
@@ -53,8 +53,6 @@
 };
 
 int rsa_key_insert(struct genlist *list, struct netaddr *src, struct netaddr *dst, RSA *rsa);
-struct rsa_key *rsa_key_dup(struct rsa_key *key);
-void rsa_key_free(void *data);
 void rsa_key_dump(struct genlist *list);
 
 struct genlist *rsa_lookup_keys(struct ph1handle *iph1, int my);
diff --git a/src/racoon/sainfo.c b/src/racoon/sainfo.c
index b6577c2..afa0aac 100644
--- a/src/racoon/sainfo.c
+++ b/src/racoon/sainfo.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: sainfo.c,v 1.14 2011/02/02 15:21:34 vanhu Exp $	*/
+/*	$NetBSD: sainfo.c,v 1.7.6.1 2007/08/01 11:52:22 vanhu Exp $	*/
 
 /*	$KAME: sainfo.c,v 1.16 2003/06/27 07:32:39 sakane Exp $	*/
 
@@ -64,8 +64,7 @@
 #include "sainfo.h"
 #include "gcmalloc.h"
 
-typedef LIST_HEAD(_sitree, sainfo) sainfo_tailq_head_t;
-static sainfo_tailq_head_t sitree, sitree_save;
+static LIST_HEAD(_sitree, sainfo) sitree, sitree_save, sitree_tmp;
 
 /* %%%
  * modules for ipsec sa info
@@ -77,112 +76,88 @@
  * First pass is for sainfo from a specified peer, second for others.
  */
 struct sainfo *
-getsainfo(loc, rmt, peer, client, remoteid)
-	const vchar_t *loc, *rmt, *peer, *client;
-	uint32_t remoteid;
+getsainfo(loc, rmt, peer, remoteid)
+	const vchar_t *loc, *rmt, *peer;
+	int remoteid;
 {
 	struct sainfo *s = NULL;
+	struct sainfo *anonymous = NULL;
+	int pass = 1;
+
+	if (peer == NULL)
+		pass = 2;
 
 	/* debug level output */
 	if(loglevel >= LLV_DEBUG) {
 		char *dloc, *drmt, *dpeer, *dclient;
-
+ 
 		if (loc == NULL)
 			dloc = strdup("ANONYMOUS");
 		else
 			dloc = ipsecdoi_id2str(loc);
-
-		if (rmt == SAINFO_ANONYMOUS)
+ 
+		if (rmt == NULL)
 			drmt = strdup("ANONYMOUS");
-		else if (rmt == SAINFO_CLIENTADDR)
-			drmt = strdup("CLIENTADDR");
 		else
 			drmt = ipsecdoi_id2str(rmt);
-
+ 
 		if (peer == NULL)
 			dpeer = strdup("NULL");
 		else
 			dpeer = ipsecdoi_id2str(peer);
-
-		if (client == NULL)
-			dclient = strdup("NULL");
-		else
-			dclient = ipsecdoi_id2str(client);
-
+ 
 		plog(LLV_DEBUG, LOCATION, NULL,
-			"getsainfo params: loc=\'%s\' rmt=\'%s\' peer=\'%s\' client=\'%s\' id=%u\n",
-			dloc, drmt, dpeer, dclient, remoteid );
+			"getsainfo params: loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i\n",
+			dloc, drmt, dpeer, remoteid );
  
                 racoon_free(dloc);
                 racoon_free(drmt);
                 racoon_free(dpeer);
-                racoon_free(dclient);
 	}
 
+    again:
+	plog(LLV_DEBUG, LOCATION, NULL,
+		"getsainfo pass #%i\n", pass);
+ 
 	LIST_FOREACH(s, &sitree, chain) {
 		const char *sainfostr = sainfo2str(s);
 		plog(LLV_DEBUG, LOCATION, NULL,
 			"evaluating sainfo: %s\n", sainfostr);
 
-		if(s->remoteid != remoteid) {
-			plog(LLV_DEBUG, LOCATION, NULL,
-				"remoteid mismatch: %u != %u\n",
-				s->remoteid, remoteid);
-				continue;
-		}
+		if(s->remoteid != remoteid)
+			continue;
 
-		/* compare 'from' id value */
-		if (s->id_i != NULL)
+		if (s->id_i != NULL) {
+			if (pass == 2)
+				continue;
 			if (ipsecdoi_chkcmpids(peer, s->id_i, 0))
 				continue;
-
-		/* compare ids - client */
-		if( s->iddst == SAINFO_CLIENTADDR ) {
-			/*
-			 * This sainfo section enforces client address
-			 * checking. Prevent match if the client value
-			 * ( modecfg or tunnel address ) is NULL.
-			 */
-
-			if (client == NULL)
-				continue;
-
-			if( rmt == SAINFO_CLIENTADDR ) {
-				/*
-				 * In the case where a supplied rmt value is
-				 * also SAINFO_CLIENTADDR, we are comparing
-				 * with another sainfo to check for duplicate.
-				 * Only compare the local values to determine
-				 * a match.
-				 */
-
-				 if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0))
-					return s;
-			}
-			else {
-				/*
-				 * In the case where a supplied rmt value is
-				 * not SAINFO_CLIENTADDR, do a standard match
-				 * for local values and enforce that the rmt
-				 * id matches the client address value.
-				 */
-
-				if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
-				    !ipsecdoi_chkcmpids(rmt, client, 0))
-					return s;
-			}
-
+		} else if (pass == 1)
+			continue;
+		if (s->idsrc == NULL && s->iddst == NULL) {
+			anonymous = s;
 			continue;
 		}
 
+		/* anonymous ? */
+		if (loc == NULL) {
+			if (anonymous != NULL)
+				break;
+			continue;
+		}
 
-		/* compare ids - standard */
+		/* compare the ids */
 		if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
 		    !ipsecdoi_chkcmpids(rmt, s->iddst, 0))
 			return s;
 	}
 
-	return NULL;
+	if ((anonymous == NULL) && (pass == 1)) {
+		pass++;
+		goto again;
+	}
+
+	return anonymous;
 }
 
 struct sainfo *
@@ -211,8 +186,7 @@
 
 	if (si->idsrc)
 		vfree(si->idsrc);
-	if (si->iddst != NULL &&
-		si->iddst != SAINFO_CLIENTADDR)
+	if (si->iddst)
 		vfree(si->iddst);
 
 #ifdef ENABLE_HYBRID
@@ -223,75 +197,11 @@
 	racoon_free(si);
 }
 
-int prisainfo(s)
-	struct sainfo *s;
-{
-	/*
-	 * determine the matching priority
-	 * of an sainfo section
-	 */
-
-	int pri = 0;
-
-	if(s->remoteid)
-		pri += 3;
-
-	if(s->id_i)
-		pri += 3;
-
-	if(s->idsrc)
-		pri++;
-
-	if(s->iddst)
-		pri++;
-
-	return pri;
-}
-
 void
 inssainfo(new)
 	struct sainfo *new;
 {
-	if(LIST_EMPTY(&sitree)) {
-
-		/* first in list */
-		LIST_INSERT_HEAD(&sitree, new, chain);
-	}
-	else {
-		int npri, spri;
-		struct sainfo *s, *n;
-
-		/*
-		 * insert our new sainfo section
-		 * into our list which is sorted
-		 * based on the match priority
-		 */
-
-		npri = prisainfo(new);
-
-		s = LIST_FIRST(&sitree);
-		while (1) {
-
-			spri = prisainfo(s);
-			n = LIST_NEXT(s, chain);
-
-			if(npri > spri)
-			{
-				/* higher priority */
-				LIST_INSERT_BEFORE(s, new, chain);
-				return;
-			}
-
-			if(n == NULL)
-			{
-				/* last in list */
-				LIST_INSERT_AFTER(s, new, chain);
-				return;
-			}
-
-			s = n;
-		}
-	}
+	LIST_INSERT_HEAD(&sitree, new, chain);
 }
 
 void
@@ -366,15 +276,13 @@
 
         char *idloc = NULL, *idrmt = NULL, *id_i;
  
-        if (si->idsrc == SAINFO_ANONYMOUS)
+        if (si->idsrc == NULL)
                 idloc = strdup("ANONYMOUS");
         else
                 idloc = ipsecdoi_id2str(si->idsrc);
  
-        if (si->iddst == SAINFO_ANONYMOUS)
+        if (si->iddst == NULL)
                 idrmt = strdup("ANONYMOUS");
-	else if (si->iddst == SAINFO_CLIENTADDR)
-                idrmt = strdup("CLIENTADDR");
         else
                 idrmt = ipsecdoi_id2str(si->iddst);
  
@@ -383,7 +291,7 @@
         else
                 id_i = ipsecdoi_id2str(si->id_i);
  
-        snprintf(buf, 255, "loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%u",
+        snprintf(buf, 255, "loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i",
 		idloc, idrmt, id_i, si->remoteid);
  
         racoon_free(idloc);
@@ -393,14 +301,12 @@
         return buf;
 }
 
-void sainfo_start_reload(void){
+void save_sainfotree(void){
 	sitree_save=sitree;
 	initsainfo();
 }
 
-void sainfo_finish_reload(void){
-	sainfo_tailq_head_t sitree_tmp;
-
+void save_sainfotree_flush(void){
 	sitree_tmp=sitree;
 	sitree=sitree_save;
 	flushsainfo();
diff --git a/src/racoon/sainfo.h b/src/racoon/sainfo.h
index e708cd6..357da3f 100644
--- a/src/racoon/sainfo.h
+++ b/src/racoon/sainfo.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: sainfo.h,v 1.8 2011/02/02 15:21:34 vanhu Exp $	*/
+/*	$NetBSD: sainfo.h,v 1.5 2006/10/03 08:01:56 vanhu Exp $	*/
 
 /* Id: sainfo.h,v 1.5 2006/07/09 17:19:38 manubsd Exp */
 
@@ -36,9 +36,6 @@
 
 #include <sys/queue.h>
 
-#define SAINFO_ANONYMOUS	((void *)NULL)
-#define	SAINFO_CLIENTADDR	((void *)~0)
-
 /* SA info */
 struct sainfo {
 	vchar_t *idsrc;
@@ -47,7 +44,6 @@
 		 * idsrc and iddst are constructed body of ID payload.
 		 * that is (struct ipsecdoi_id_b) + ID value.
 		 * If idsrc == NULL, that is anonymous entry.
-		 * If idsrc == ~0, that is client address entry.
 		 */
 
 #ifdef ENABLE_HYBRID
@@ -60,7 +56,7 @@
 	vchar_t *id_i;		/* identifier of the authorized initiator */
 	struct sainfoalg *algs[MAXALGCLASS];
 
-	uint32_t remoteid;
+	int remoteid;
 
 	LIST_ENTRY(sainfo) chain;
 };
@@ -73,7 +69,7 @@
 };
 
 extern struct sainfo *getsainfo __P((const vchar_t *,
-	const vchar_t *, const vchar_t *, const vchar_t *, uint32_t));
+	const vchar_t *, const vchar_t *, int));
 extern struct sainfo *newsainfo __P((void));
 extern void delsainfo __P((struct sainfo *));
 extern void inssainfo __P((struct sainfo *));
@@ -85,8 +81,8 @@
 extern void inssainfoalg __P((struct sainfoalg **, struct sainfoalg *));
 extern const char * sainfo2str __P((const struct sainfo *));
 
-extern void sainfo_start_reload __P((void));
-extern void sainfo_finish_reload __P((void));
+extern void save_sainfotree __P((void));
+extern void save_sainfotree_flush __P((void));
 extern void save_sainfotree_restore __P((void));
 
 #endif /* _SAINFO_H */
diff --git a/src/racoon/samples/roadwarrior/client/phase1-down.sh b/src/racoon/samples/roadwarrior/client/phase1-down.sh
index 92f2ba8..8edc187 100755
--- a/src/racoon/samples/roadwarrior/client/phase1-down.sh
+++ b/src/racoon/samples/roadwarrior/client/phase1-down.sh
@@ -8,10 +8,10 @@
 
 case `uname -s` in
 NetBSD)
-	DEFAULT_GW=`netstat -finet -rn | awk '($1 == "default"){print $2; exit}'`
+	DEFAULT_GW=`netstat -rn | awk '($1 == "default"){print $2}'`
 	;;
 Linux)
-	DEFAULT_GW=`netstat --inet -rn | awk '($1 == "0.0.0.0"){print $2; exit}'`
+	DEFAULT_GW=`netstat -rn | awk '($1 == "0.0.0.0"){print $2}'`
 	;;
 esac
 
@@ -21,29 +21,24 @@
 echo "REMOTE_ADDR = ${REMOTE_ADDR}"
 echo "REMOTE_PORT = ${REMOTE_PORT}"
 echo "DEFAULT_GW = ${DEFAULT_GW}"
-echo "INTERNAL_NETMASK4 = ${INTERNAL_NETMASK4}"
 echo "INTERNAL_ADDR4 = ${INTERNAL_ADDR4}"
 echo "INTERNAL_DNS4 = ${INTERNAL_DNS4}"
 
 echo ${INTERNAL_ADDR4} | grep '[0-9]' > /dev/null || exit 0
-echo ${INTERNAL_NETMASK4} | grep '[0-9]' > /dev/null || exit 0
 echo ${DEFAULT_GW} | grep '[0-9]' > /dev/null || exit 0
 
-if [ -f /etc/resolv.conf.bak ]; then
-	rm -f /etc/resolv.conf
-	mv /etc/resolv.conf.bak /etc/resolv.conf
-fi
+test -f /etc/resolv.conf.bak && cp /etc/resolv.conf.bak /etc/resolv.conf
 
 case `uname -s` in
 NetBSD)
-	if=`netstat -finet -rn|awk '($1 == "default"){print $7; exit}'`
+	if=`netstat -rn|awk '($1 == "default"){print $7}'`
+	ifconfig ${if} delete ${INTERNAL_ADDR4}
 	route delete default
 	route delete ${REMOTE_ADDR}
-	ifconfig ${if} delete ${INTERNAL_ADDR4}
 	route add default ${DEFAULT_GW} -ifa ${LOCAL_ADDR}
 	;;
 Linux)
-	if=`netstat --inet -rn|awk '($1 == "0.0.0.0"){print $8; exit}'`
+	if=`netstat -rn|awk '($1 == "0.0.0.0"){print $8}'`
 	route delete default
 	route delete ${REMOTE_ADDR}
 	ifconfig ${if}:1 del ${INTERNAL_ADDR4}
@@ -59,13 +54,13 @@
 	;;
 esac
 
-LOCAL="${LOCAL_ADDR}"
-REMOTE="${REMOTE_ADDR}"
-if [ "x${LOCAL_PORT}" != "x500" ]; then
-	# NAT-T setup
-	LOCAL="${LOCAL}[${LOCAL_PORT}]"
-	REMOTE="${REMOTE}[${REMOTE_PORT}]"
-fi
+# Use this for a NAT-T setup
+LOCAL="${LOCAL_ADDR}[${LOCAL_PORT}]"
+REMOTE="${REMOTE_ADDR}[${REMOTE_PORT}]"
+
+# Use this for a non NAT-T setup
+#LOCAL="${LOCAL_ADDR}"
+#REMOTE="${REMOTE_ADDR}"
 
 echo "
 deleteall ${REMOTE_ADDR} ${LOCAL_ADDR} esp;
diff --git a/src/racoon/samples/roadwarrior/client/phase1-up.sh b/src/racoon/samples/roadwarrior/client/phase1-up.sh
index 9275811..e45b648 100755
--- a/src/racoon/samples/roadwarrior/client/phase1-up.sh
+++ b/src/racoon/samples/roadwarrior/client/phase1-up.sh
@@ -7,10 +7,10 @@
 
 case `uname -s` in
 NetBSD)
-	DEFAULT_GW=`netstat -finet -rn | awk '($1 == "default"){print $2; exit}'`
+	DEFAULT_GW=`netstat -rn | awk '($1 == "default"){print $2}'`
 	;;
 Linux)
-	DEFAULT_GW=`netstat --inet -rn | awk '($1 == "0.0.0.0"){print $2; exit}'`
+	DEFAULT_GW=`netstat -rn | awk '($1 == "0.0.0.0"){print $2}'`
 	;;
 esac
 
@@ -21,28 +21,25 @@
 echo "REMOTE_PORT = ${REMOTE_PORT}"
 echo "DEFAULT_GW = ${DEFAULT_GW}"
 echo "INTERNAL_ADDR4 = ${INTERNAL_ADDR4}"
-echo "INTERNAL_NETMASK4 = ${INTERNAL_NETMASK4}"
 echo "INTERNAL_DNS4 = ${INTERNAL_DNS4}"
 
 echo ${INTERNAL_ADDR4} | grep '[0-9]' > /dev/null || exit 0
-echo ${INTERNAL_NETMASK4} | grep '[0-9]' > /dev/null || exit 0
 echo ${DEFAULT_GW} | grep '[0-9]' > /dev/null || exit 0
 
-mv /etc/resolv.conf /etc/resolv.conf.bak
-( umask 22; touch /etc/resolv.conf )
-echo "# Generated by racoon on `date`" >> /etc/resolv.conf
+test -f /etc/resolv.conf.bak || cp /etc/resolv.conf /etc/resolv.conf.bak
+echo "# Generated by racoon on `date`" > /etc/resolv.conf
 echo "nameserver ${INTERNAL_DNS4}" >> /etc/resolv.conf
 
 case `uname -s` in
 NetBSD)
-	if=`netstat -finet -rn|awk '($1 == "default"){print $7; exit}'`
+	if=`netstat -rn|awk '($1 == "default"){print $7}'`
 	ifconfig ${if} alias ${INTERNAL_ADDR4} netmask ${INTERNAL_NETMASK4}
 	route delete default
 	route add default ${DEFAULT_GW} -ifa ${INTERNAL_ADDR4}
 	route add ${REMOTE_ADDR} ${DEFAULT_GW}
 	;;
 Linux)
-	if=`netstat --inet -rn|awk '($1 == "0.0.0.0"){print $8; exit}'`
+	if=`netstat -rn|awk '($1 == "0.0.0.0"){print $8}'`
 	ifconfig ${if}:1 ${INTERNAL_ADDR4}      
 	route delete default
 	route add ${REMOTE_ADDR} gw ${DEFAULT_GW} dev ${if}
@@ -50,13 +47,13 @@
 	;;
 esac
 
-LOCAL="${LOCAL_ADDR}"
-REMOTE="${REMOTE_ADDR}"
-if [ "x${LOCAL_PORT}" != "x500" ]; then
-	# NAT-T setup
-	LOCAL="${LOCAL}[${LOCAL_PORT}]"
-	REMOTE="${REMOTE}[${REMOTE_PORT}]"
-fi
+# Use this for a NAT-T setup
+LOCAL="${LOCAL_ADDR}[${LOCAL_PORT}]"
+REMOTE="${REMOTE_ADDR}[${REMOTE_PORT}]"
+
+# Use this for a non NAT-T setup
+#LOCAL="${LOCAL_ADDR}"
+#REMOTE="${REMOTE_ADDR}"
 
 
 echo "
diff --git a/src/racoon/schedule.c b/src/racoon/schedule.c
index 018f920..04723c5 100644
--- a/src/racoon/schedule.c
+++ b/src/racoon/schedule.c
@@ -1,10 +1,9 @@
-/*	$NetBSD: schedule.c,v 1.7 2009/01/23 09:10:13 tteras Exp $	*/
+/*	$NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /*	$KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2008 Timo Teras.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -41,7 +40,6 @@
 #include <sys/socket.h>
 
 #include <stdlib.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -53,46 +51,25 @@
 #include "var.h"
 #include "gcmalloc.h"
 
+#define FIXY2038PROBLEM
+
 #ifndef TAILQ_FOREACH
 #define TAILQ_FOREACH(elm, head, field) \
         for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field))
 #endif
 
+static struct timeval timeout;
+
+#ifdef FIXY2038PROBLEM
+#define Y2038TIME_T	0x7fffffff
+static time_t launched;		/* time when the program launched. */
+static time_t deltaY2038;
+#endif
+
 static TAILQ_HEAD(_schedtree, sched) sctree;
 
-void
-sched_get_monotonic_time(tv)
-	struct timeval *tv;
-{
-#ifdef HAVE_CLOCK_MONOTONIC
-	struct timespec ts;
-
-	clock_gettime(CLOCK_MONOTONIC, &ts);
-	tv->tv_sec = ts.tv_sec;
-	tv->tv_usec = ts.tv_nsec / 1000;
-#else
-	gettimeofday(tv, NULL);
-#endif
-}
-
-time_t
-sched_monotonic_to_time_t(tv, now)
-	struct timeval *tv, *now;
-{
-#ifdef HAVE_CLOCK_MONOTONIC
-	struct timeval mynow, res;
-
-	if (now == NULL) {
-		sched_get_monotonic_time(&mynow);
-		now = &mynow;
-	}
-	timersub(now, tv, &res);
-
-	return time(NULL) + res.tv_sec;
-#else
-	return tv->tv_sec;
-#endif
-}
+static void sched_add __P((struct sched *));
+static time_t current_time __P((void));
 
 /*
  * schedule handler
@@ -103,26 +80,42 @@
 struct timeval *
 schedular()
 {
-	static struct timeval timeout;
-	struct timeval now;
-	struct sched *p;
+	time_t now, delta;
+	struct sched *p, *next = NULL;
 
-	sched_get_monotonic_time(&now);
-	while (!TAILQ_EMPTY(&sctree) &&
-		timercmp(&TAILQ_FIRST(&sctree)->xtime, &now, <=)) {
-		void (*func)(struct sched *);
+	now = current_time();
 
-		p = TAILQ_FIRST(&sctree);
-		func = p->func;
-		sched_cancel(p);
-		func(p);
+        for (p = TAILQ_FIRST(&sctree); p; p = next) {
+		/* if the entry has been daed, remove it */
+		if (p->dead)
+			goto next_schedule;
+
+		/* if the time hasn't come, proceed to the next entry */
+		if (now < p->xtime) {
+			next = TAILQ_NEXT(p, chain);
+			continue;
+		}
+
+		/* mark it with dead. and call the function. */
+		p->dead = 1;
+		if (p->func != NULL)
+			(p->func)(p->param);
+
+	   next_schedule:
+		next = TAILQ_NEXT(p, chain);
+		TAILQ_REMOVE(&sctree, p, chain);
+		racoon_free(p);
 	}
 
 	p = TAILQ_FIRST(&sctree);
 	if (p == NULL)
 		return NULL;
 
-	timersub(&p->xtime, &now, &timeout);
+	now = current_time();
+
+	delta = p->xtime - now;
+	timeout.tv_sec = delta < 0 ? 0 : delta;
+	timeout.tv_usec = 0;
 
 	return &timeout;
 }
@@ -130,46 +123,101 @@
 /*
  * add new schedule to schedule table.
  */
-void
-sched_schedule(sc, tick, func)
-	struct sched *sc;
+struct sched *
+sched_new(tick, func, param)
 	time_t tick;
-	void (*func) __P((struct sched *));
+	void (*func) __P((void *));
+	void *param;
 {
 	static long id = 1;
-	struct sched *p;
-	struct timeval now;
+	struct sched *new;
 
-	sched_cancel(sc);
+	new = (struct sched *)racoon_malloc(sizeof(*new));
+	if (new == NULL)
+		return NULL;
 
-	sc->func = func;
-	sc->id = id++;
-	sc->tick.tv_sec = tick;
-	sc->tick.tv_usec = 0;
-	sched_get_monotonic_time(&now);
-	timeradd(&now, &sc->tick, &sc->xtime);
+	memset(new, 0, sizeof(*new));
+	new->func = func;
+	new->param = param;
+
+	new->id = id++;
+	time(&new->created);
+	new->tick = tick;
+
+	new->xtime = current_time() + tick;
+	new->dead = 0;
 
 	/* add to schedule table */
+	sched_add(new);
+
+	return(new);
+}
+
+/* add new schedule to schedule table */
+static void
+sched_add(sc)
+	struct sched *sc;
+{
+	struct sched *p;
+
 	TAILQ_FOREACH(p, &sctree, chain) {
-		if (timercmp(&sc->xtime, &p->xtime, <))
-			break;
+		if (sc->xtime < p->xtime) {
+			TAILQ_INSERT_BEFORE(p, sc, chain);
+			return;
+		}
 	}
 	if (p == NULL)
 		TAILQ_INSERT_TAIL(&sctree, sc, chain);
-	else
-		TAILQ_INSERT_BEFORE(p, sc, chain);
+
+	return;
 }
 
-/*
- * cancel scheduled callback
+/* get current time.
+ * if defined FIXY2038PROBLEM, base time is the time when called sched_init().
+ * Otherwise, conform to time(3).
  */
+static time_t
+current_time()
+{
+	time_t n;
+#ifdef FIXY2038PROBLEM
+	time_t t;
+
+	time(&n);
+	t = n - launched;
+	if (t < 0)
+		t += deltaY2038;
+
+	return t;
+#else
+	return time(&n);
+#endif
+}
+
 void
-sched_cancel(sc)
+sched_kill(sc)
 	struct sched *sc;
 {
-	if (sc->func != NULL) {
-		TAILQ_REMOVE(&sctree, sc, chain);
-		sc->func = NULL;
+	sc->dead = 1;
+
+	return;
+}
+
+/* XXX this function is probably unnecessary. */
+void
+sched_scrub_param(param)
+	void *param;
+{
+	struct sched *sc;
+
+	TAILQ_FOREACH(sc, &sctree, chain) {
+		if (sc->param == param) {
+			if (!sc->dead) {
+				plog(LLV_DEBUG, LOCATION, NULL,
+				    "an undead schedule has been deleted.\n");
+			}
+			sched_kill(sc);
+		}
 	}
 }
 
@@ -184,7 +232,6 @@
 	caddr_t new;
 	struct sched *p;
 	struct scheddump *dst;
-	struct timeval now, created;
 	int cnt = 0;
 
 	/* initialize */
@@ -205,14 +252,12 @@
 		return -1;
 	dst = (struct scheddump *)new;
 
-	sched_get_monotonic_time(&now);
-	p = TAILQ_FIRST(&sctree);
+        p = TAILQ_FIRST(&sctree);
 	while (p) {
-		timersub(&p->xtime, &p->tick, &created);
-		dst->xtime = p->xtime.tv_sec;
+		dst->xtime = p->xtime;
 		dst->id = p->id;
-		dst->created = sched_monotonic_to_time_t(&created, &now);
-		dst->tick = p->tick.tv_sec;
+		dst->created = p->created;
+		dst->tick = p->tick;
 
 		p = TAILQ_NEXT(p, chain);
 		if (p == NULL)
@@ -229,7 +274,15 @@
 void
 sched_init()
 {
+#ifdef FIXY2038PROBLEM
+	time(&launched);
+
+	deltaY2038 = Y2038TIME_T - launched;
+#endif
+
 	TAILQ_INIT(&sctree);
+
+	return;
 }
 
 #ifdef STEST
diff --git a/src/racoon/schedule.h b/src/racoon/schedule.h
index 228e677..bd66593 100644
--- a/src/racoon/schedule.h
+++ b/src/racoon/schedule.h
@@ -1,10 +1,9 @@
-/*	$NetBSD: schedule.h,v 1.8 2009/08/17 12:00:53 vanhu Exp $	*/
+/*	$NetBSD: schedule.h,v 1.4.6.1 2007/03/21 14:29:48 vanhu Exp $	*/
 
 /* Id: schedule.h,v 1.5 2006/05/03 21:53:42 vanhu Exp */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2008 Timo Teras.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -35,47 +34,39 @@
 #ifndef _SCHEDULE_H
 #define _SCHEDULE_H
 
-#include <stddef.h>
-
 #include <sys/queue.h>
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
 #include "gnuc.h"
 
-#ifndef offsetof
-#ifdef __compiler_offsetof
-#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#endif
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({                      \
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-
 /* scheduling table */
 /* the head is the nearest event. */
 struct sched {
-	void (*func) __P((struct sched *));	/* callback on timeout */
-	struct timeval xtime;			/* expiration time */
-	struct timeval tick;			/* relative timeout */
+	time_t xtime;		/* event time which is as time(3). */
+				/*
+				 * if defined FIXY2038PROBLEM, this time
+				 * is from the time when called sched_init().
+				 */
+	void (*func) __P((void *)); /* call this function when timeout. */
+	void *param;		/* pointer to parameter */
+
+	int dead;		/* dead or alive */
+	long id;		/* for debug */
+	time_t created;		/* for debug */
+	time_t tick;		/* for debug */
+
 	TAILQ_ENTRY(sched) chain;
-	long id;				/* for debug */
 };
 
-#define SCHED_INITIALIZER() { NULL, }
+/* cancel schedule */
+#define SCHED_KILL(s)                                                          \
+do {                                                                           \
+	if(s != NULL){	   														\
+		sched_kill(s);                                                         \
+		s = NULL;                                                              \
+	}\
+} while(0)
+
+/* must be called after it's called from scheduler. */
+#define SCHED_INIT(s)	(s) = NULL
 
 struct scheddump {
 	time_t xtime;
@@ -84,16 +75,11 @@
 	time_t tick;
 };
 
-time_t sched_monotonic_to_time_t __P((struct timeval *tv,
-				      struct timeval *now));
-void sched_get_monotonic_time __P((struct timeval *tv));
-
 struct timeval *schedular __P((void));
-void sched_schedule __P((struct sched *, time_t,
-			 void (*func) __P((struct sched *))));
-void sched_cancel __P((struct sched *));
-
+struct sched *sched_new __P((time_t, void (*func) __P((void *)), void *));
+void sched_kill __P((struct sched *));
 int sched_dump __P((caddr_t *, int *));
 void sched_init __P((void));
+void sched_scrub_param __P((void *));
 
 #endif /* _SCHEDULE_H */
diff --git a/src/racoon/session.c b/src/racoon/session.c
index 85e29a3..9db901d 100644
--- a/src/racoon/session.c
+++ b/src/racoon/session.c
@@ -1,11 +1,11 @@
-/*	$NetBSD: session.c,v 1.32 2011/03/02 15:09:16 vanhu Exp $	*/
+/*	$NetBSD: session.c,v 1.7.6.2 2007/08/01 11:52:22 vanhu Exp $	*/
 
 /*	$KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -17,7 +17,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -59,7 +59,6 @@
 #include <signal.h>
 #include <sys/stat.h>
 #include <paths.h>
-#include <err.h>
 
 #include <netinet/in.h>
 #include <resolv.h>
@@ -78,8 +77,6 @@
 #include "evt.h"
 #include "cfparse_proto.h"
 #include "isakmp_var.h"
-#include "isakmp.h"
-#include "isakmp_var.h"
 #include "isakmp_xauth.h"
 #include "isakmp_cfg.h"
 #include "admin_var.h"
@@ -91,174 +88,80 @@
 #include "localconf.h"
 #include "remoteconf.h"
 #include "backupsa.h"
-#include "remoteconf.h"
 #ifdef ENABLE_NATT
 #include "nattraversal.h"
 #endif
 
+
 #include "algorithm.h" /* XXX ??? */
 
 #include "sainfo.h"
 
-struct fd_monitor {
-	int (*callback)(void *ctx, int fd);
-	void *ctx;
-	int prio;
-	int fd;
-	TAILQ_ENTRY(fd_monitor) chain;
-};
-
-#define NUM_PRIORITIES 2
-
 static void close_session __P((void));
+static void check_rtsock __P((void *));
 static void initfds __P((void));
 static void init_signal __P((void));
 static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int))));
 static void check_sigreq __P((void));
+static void check_flushsa_stub __P((void *));
 static void check_flushsa __P((void));
 static int close_sockets __P((void));
 
-static fd_set preset_mask, active_mask;
-static struct fd_monitor fd_monitors[FD_SETSIZE];
-static TAILQ_HEAD(fd_monitor_list, fd_monitor) fd_monitor_tree[NUM_PRIORITIES];
+static fd_set mask0;
+static fd_set maskdying;
 static int nfds = 0;
-
 static volatile sig_atomic_t sigreq[NSIG + 1];
-static struct sched scflushsa = SCHED_INITIALIZER();
-
-void
-monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority)
-{
-	if (fd < 0 || fd >= FD_SETSIZE) {
-		plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun");
-		exit(1);
-	}
-
-	FD_SET(fd, &preset_mask);
-	if (fd > nfds)
-		nfds = fd;
-	if (priority <= 0)
-		priority = 0;
-	if (priority >= NUM_PRIORITIES)
-		priority = NUM_PRIORITIES - 1;
-
-	fd_monitors[fd].callback = callback;
-	fd_monitors[fd].ctx = ctx;
-	fd_monitors[fd].prio = priority;
-	fd_monitors[fd].fd = fd;
-	TAILQ_INSERT_TAIL(&fd_monitor_tree[priority],
-			  &fd_monitors[fd], chain);
-}
-
-void
-unmonitor_fd(int fd)
-{
-	if (fd < 0 || fd >= FD_SETSIZE) {
-		plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun");
-		exit(1);
-	}
-
-	if (fd_monitors[fd].callback == NULL)
-		return;
-
-	FD_CLR(fd, &preset_mask);
-	FD_CLR(fd, &active_mask);
-	fd_monitors[fd].callback = NULL;
-	fd_monitors[fd].ctx = NULL;
-	TAILQ_REMOVE(&fd_monitor_tree[fd_monitors[fd].prio],
-		     &fd_monitors[fd], chain);
-}
+static int dying = 0;
 
 int
 session(void)
 {
+	fd_set rfds;
 	struct timeval *timeout;
 	int error;
+	struct myaddrs *p;
 	char pid_file[MAXPATHLEN];
 	FILE *fp;
 	pid_t racoon_pid = 0;
-	int i, count;
-	struct fd_monitor *fdm;
-
-	nfds = 0;
-	FD_ZERO(&preset_mask);
-
-	for (i = 0; i < NUM_PRIORITIES; i++)
-		TAILQ_INIT(&fd_monitor_tree[i]);
+	int i;
 
 	/* initialize schedular */
 	sched_init();
+
 	init_signal();
 
-	if (pfkey_init() < 0)
-		errx(1, "failed to initialize pfkey socket");
-
-	if (isakmp_init() < 0)
-		errx(1, "failed to initialize ISAKMP structures");
-
-#ifdef ENABLE_HYBRID
-	if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD))
-		errx(1, "could not initialize ISAKMP mode config structures");
-#endif
-
-#ifdef HAVE_LIBLDAP
-	if (xauth_ldap_init_conf() != 0)
-		errx(1, "could not initialize ldap config");
-#endif
-
-#ifdef HAVE_LIBRADIUS
-	if (xauth_radius_init_conf(0) != 0)
-		errx(1, "could not initialize radius config");
-#endif
-
-	myaddr_init_lists();
-
-	/*
-	 * in order to prefer the parameters by command line,
-	 * saving some parameters before parsing configuration file.
-	 */
-	save_params();
-	if (cfparse() != 0)
-		errx(1, "failed to parse configuration file.");
-	restore_params();
-
 #ifdef ENABLE_ADMINPORT
 	if (admin_init() < 0)
-		errx(1, "failed to initialize admin port socket");
+		exit(1);
 #endif
 
+	initmyaddr();
 
-#ifdef ENABLE_HYBRID
-	if(isakmp_cfg_config.network4 && isakmp_cfg_config.pool_size == 0)
-		if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
-			return error;
-#endif
+	if (isakmp_init() < 0)
+		exit(1);
 
-	if (dump_config)
-		dumprmconf();
-
-#ifdef HAVE_LIBRADIUS
-	if (xauth_radius_init() != 0)
-		errx(1, "could not initialize libradius");
-#endif
-
-	if (myaddr_init() != 0)
-		errx(1, "failed to listen to configured addresses");
-	myaddr_sync();
+	initfds();
 
 #ifdef ENABLE_NATT
 	natt_keepalive_init ();
 #endif
 
+	if (privsep_init() != 0)
+		exit(1);
+
+	for (i = 0; i <= NSIG; i++)
+		sigreq[i] = 0;
+
 	/* write .pid file */
-	if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL)
+	racoon_pid = getpid();
+	if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) 
 		strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN);
-	else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/')
+	else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') 
 		strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
 	else {
 		strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN);
 		strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN);
-	}
+	} 
 	fp = fopen(pid_file, "w");
 	if (fp) {
 		if (fchmod(fileno(fp),
@@ -267,26 +170,19 @@
 			fclose(fp);
 			exit(1);
 		}
+		fprintf(fp, "%ld\n", (long)racoon_pid);
+		fclose(fp);
 	} else {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"cannot open %s", pid_file);
 	}
 
-	if (privsep_init() != 0)
-		exit(1);
-
-	/*
-	 * The fork()'ed privileged side will close its copy of fp.  We wait
-	 * until here to get the correct child pid.
-	 */
-	racoon_pid = getpid();
-	fprintf(fp, "%ld\n", (long)racoon_pid);
-	fclose(fp);
-
-	for (i = 0; i <= NSIG; i++)
-		sigreq[i] = 0;
-
 	while (1) {
+		if (dying)
+			rfds = maskdying;
+		else
+			rfds = mask0;
+
 		/*
 		 * asynchronous requests via signal.
 		 * make sure to reset sigreq to 0.
@@ -296,11 +192,7 @@
 		/* scheduling */
 		timeout = schedular();
 
-		/* schedular can change select() mask, so we reset
-		 * the working copy here */
-		active_mask = preset_mask;
-
-		error = select(nfds + 1, &active_mask, NULL, NULL, timeout);
+		error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout);
 		if (error < 0) {
 			switch (errno) {
 			case EINTR:
@@ -314,24 +206,28 @@
 			/*NOTREACHED*/
 		}
 
-		count = 0;
-		for (i = 0; i < NUM_PRIORITIES; i++) {
-			TAILQ_FOREACH(fdm, &fd_monitor_tree[i], chain) {
-				if (!FD_ISSET(fdm->fd, &active_mask))
-					continue;
+#ifdef ENABLE_ADMINPORT
+		if ((lcconf->sock_admin != -1) &&
+		    (FD_ISSET(lcconf->sock_admin, &rfds)))
+			admin_handler();
+#endif
 
-				FD_CLR(fdm->fd, &active_mask);
-				if (fdm->callback != NULL) {
-					fdm->callback(fdm->ctx, fdm->fd);
-					count++;
-				} else
-					plog(LLV_ERROR, LOCATION, NULL,
-					"fd %d set, but no active callback\n", i);
-			}
-			if (count != 0)
-				break;
+		for (p = lcconf->myaddrs; p; p = p->next) {
+			if (!p->addr)
+				continue;
+			if (FD_ISSET(p->sock, &rfds))
+				isakmp_handler(p->sock);
 		}
 
+		if (FD_ISSET(lcconf->sock_pfkey, &rfds))
+			pfkey_handler();
+
+		if (lcconf->rtsock >= 0 && FD_ISSET(lcconf->rtsock, &rfds)) {
+			if (update_myaddrs() && lcconf->autograbaddr)
+				check_rtsock(NULL);
+			else
+				initfds();
+		}
 	}
 }
 
@@ -339,20 +235,84 @@
 static void
 close_session()
 {
-	evt_generic(EVT_RACOON_QUIT, NULL);
-	pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC);
+#ifdef ENABLE_FASTQUIT
 	flushph2();
+#endif
 	flushph1();
-	flushrmconf();
-	flushsainfo();
 	close_sockets();
 	backupsa_clean();
 
-	plog(LLV_INFO, LOCATION, NULL, "racoon process %d shutdown\n", getpid());
-
+	plog(LLV_INFO, LOCATION, NULL, "racoon shutdown\n");
 	exit(0);
 }
 
+static void
+check_rtsock(unused)
+	void *unused;
+{
+	isakmp_close();
+	grab_myaddrs();
+	autoconf_myaddrsport();
+	isakmp_open();
+
+	/* initialize socket list again */
+	initfds();
+}
+
+static void
+initfds()
+{
+	struct myaddrs *p;
+
+	nfds = 0;
+
+	FD_ZERO(&mask0);
+	FD_ZERO(&maskdying);
+
+#ifdef ENABLE_ADMINPORT
+	if (lcconf->sock_admin != -1) {
+		if (lcconf->sock_admin >= FD_SETSIZE) {
+			plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n");
+			exit(1);
+		}
+		FD_SET(lcconf->sock_admin, &mask0);
+		/* XXX should we listen on admin socket when dying ?
+		 */
+#if 0
+		FD_SET(lcconf->sock_admin, &maskdying);
+#endif
+		nfds = (nfds > lcconf->sock_admin ? nfds : lcconf->sock_admin);
+	}
+#endif
+	if (lcconf->sock_pfkey >= FD_SETSIZE) {
+		plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n");
+		exit(1);
+	}
+	FD_SET(lcconf->sock_pfkey, &mask0);
+	FD_SET(lcconf->sock_pfkey, &maskdying);
+	nfds = (nfds > lcconf->sock_pfkey ? nfds : lcconf->sock_pfkey);
+	if (lcconf->rtsock >= 0) {
+		if (lcconf->rtsock >= FD_SETSIZE) {
+			plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n");
+			exit(1);
+		}
+		FD_SET(lcconf->rtsock, &mask0);
+		nfds = (nfds > lcconf->rtsock ? nfds : lcconf->rtsock);
+	}
+
+	for (p = lcconf->myaddrs; p; p = p->next) {
+		if (!p->addr)
+			continue;
+		if (p->sock >= FD_SETSIZE) {
+			plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n");
+			exit(1);
+		}
+		FD_SET(p->sock, &mask0);
+		nfds = (nfds > p->sock ? nfds : p->sock);
+	}
+	nfds++;
+}
+
 static int signals[] = {
 	SIGHUP,
 	SIGINT,
@@ -371,7 +331,10 @@
 signal_handler(sig)
 	int sig;
 {
-	sigreq[sig] = 1;
+	/* Do not just set it to 1, because we may miss some signals by just setting
+	 * values to 0/1
+	 */
+	sigreq[sig]++;
 }
 
 
@@ -382,28 +345,27 @@
 
 #ifdef ENABLE_HYBRID
 	if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) {
-		plog(LLV_ERROR, LOCATION, NULL,
+		plog(LLV_ERROR, LOCATION, NULL, 
 		    "ISAKMP mode config structure reset failed, "
 		    "not reloading\n");
 		return;
 	}
 #endif
 
-	sainfo_start_reload();
+	save_sainfotree();
 
 	/* TODO: save / restore / flush old lcconf (?) / rmtree
 	 */
-	rmconf_start_reload();
+/*	initlcconf();*/ /* racoon_conf ? ! */
 
-#ifdef HAVE_LIBRADIUS
-	/* free and init radius configuration */
-	xauth_radius_init_conf(1);
-#endif
+	save_rmconf();
+	initrmconf();
 
-	pfkey_reload();
-
+	/* Do a part of pfkey_init() ?
+	 * SPD reload ?
+	 */
+	
 	save_params();
-	flushlcconf();
 	error = cfparse();
 	if (error != 0){
 		plog(LLV_ERROR, LOCATION, NULL, "config reload failed\n");
@@ -412,17 +374,19 @@
 	}
 	restore_params();
 
-#if 0
+#if 0	
 	if (dump_config)
 		dumprmconf ();
 #endif
 
-	myaddr_sync();
-
-#ifdef HAVE_LIBRADIUS
-	/* re-initialize radius state */
-	xauth_radius_init();
-#endif
+	/* 
+	 * init_myaddr() ?
+	 * If running in privilege separation, do not reinitialize
+	 * the IKE listener, as we will not have the right to 
+	 * setsockopt(IP_IPSEC_POLICY). 
+	 */
+	if (geteuid() == 0)
+		check_rtsock(NULL);
 
 	/* Revalidate ph1 / ph2tree !!!
 	 * update ctdtree if removing some ph1 !
@@ -431,33 +395,44 @@
 	/* Update ctdtree ?
 	 */
 
-	sainfo_finish_reload();
-	rmconf_finish_reload();
+	save_sainfotree_flush();
+	save_rmconf_flush();
 }
 
 static void
 check_sigreq()
 {
-	int sig, s;
+	int sig;
 
+	/* 
+	 * XXX We are not able to tell if we got 
+	 * several time the same signal. This is
+	 * not a problem for the current code, 
+	 * but we shall remember this limitation.
+	 */
 	for (sig = 0; sig <= NSIG; sig++) {
 		if (sigreq[sig] == 0)
 			continue;
-		sigreq[sig] = 0;
 
+		sigreq[sig]--;
 		switch(sig) {
 		case 0:
 			return;
-
+			
+			/* Catch up childs, mainly scripts.
+			 */
 		case SIGCHLD:
-			/* Reap all pending children */
-			while (waitpid(-1, &s, WNOHANG) > 0)
-				;
-			break;
+	    {
+			pid_t pid;
+			int s;
+			
+			pid = wait(&s);
+	    }
+		break;
 
 #ifdef DEBUG_RECORD_MALLOCATION
-		/*
-		 * XXX This operation is signal handler unsafe and may lead to
+		/* 
+		 * XXX This operation is signal handler unsafe and may lead to 
 		 * crashes and security breaches: See Henning Brauer talk at
 		 * EuroBSDCon 2005. Do not run in production with this option
 		 * enabled.
@@ -473,31 +448,108 @@
 			break;
 
 		case SIGINT:
-		case SIGTERM:
-			plog(LLV_INFO, LOCATION, NULL,
+		case SIGTERM:			
+			plog(LLV_INFO, LOCATION, NULL, 
 			    "caught signal %d\n", sig);
+			EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL);
+			pfkey_send_flush(lcconf->sock_pfkey, 
+			    SADB_SATYPE_UNSPEC);
+#ifdef ENABLE_FASTQUIT
 			close_session();
+#else
+			sched_new(1, check_flushsa_stub, NULL);
+#endif
+			dying = 1;
 			break;
 
 		default:
-			plog(LLV_INFO, LOCATION, NULL,
+			plog(LLV_INFO, LOCATION, NULL, 
 			    "caught signal %d\n", sig);
 			break;
 		}
 	}
 }
 
+/*
+ * waiting the termination of processing until sending DELETE message
+ * for all inbound SA will complete.
+ */
+static void
+check_flushsa_stub(p)
+	void *p;
+{
+
+	check_flushsa();
+}
+
+static void
+check_flushsa()
+{
+	vchar_t *buf;
+	struct sadb_msg *msg, *end, *next;
+	struct sadb_sa *sa;
+	caddr_t mhp[SADB_EXT_MAX + 1];
+	int n;
+
+	buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
+	if (buf == NULL) {
+		plog(LLV_DEBUG, LOCATION, NULL,
+		    "pfkey_dump_sadb: returned nothing.\n");
+		return;
+	}
+
+	msg = (struct sadb_msg *)buf->v;
+	end = (struct sadb_msg *)(buf->v + buf->l);
+
+	/* counting SA except of dead one. */
+	n = 0;
+	while (msg < end) {
+		if (PFKEY_UNUNIT64(msg->sadb_msg_len) < sizeof(*msg))
+			break;
+		next = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len));
+		if (msg->sadb_msg_type != SADB_DUMP) {
+			msg = next;
+			continue;
+		}
+
+		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
+			plog(LLV_ERROR, LOCATION, NULL,
+				"pfkey_check (%s)\n", ipsec_strerror());
+			msg = next;
+			continue;
+		}
+
+		sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
+		if (!sa) {
+			msg = next;
+			continue;
+		}
+
+		if (sa->sadb_sa_state != SADB_SASTATE_DEAD) {
+			n++;
+			msg = next;
+			continue;
+		}
+
+		msg = next;
+	}
+
+	if (buf != NULL)
+		vfree(buf);
+
+	if (n) {
+		sched_new(1, check_flushsa_stub, NULL);
+		return;
+	}
+
+	close_session();
+}
+
 static void
 init_signal()
 {
 	int i;
 
-	/*
-	 * Ignore SIGPIPE as we check the return value of system calls
-	 * that write to pipe-like fds.
-	 */
-	signal(SIGPIPE, SIG_IGN);
-
 	for (i = 0; signals[i] != 0; i++)
 		if (set_signal(signals[i], signal_handler) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
@@ -530,7 +582,7 @@
 static int
 close_sockets()
 {
-	myaddr_close();
+	isakmp_close();
 	pfkey_close(lcconf->sock_pfkey);
 #ifdef ENABLE_ADMINPORT
 	(void)admin_close();
diff --git a/src/racoon/session.h b/src/racoon/session.h
index 7764c62..58799ee 100644
--- a/src/racoon/session.h
+++ b/src/racoon/session.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: session.h,v 1.9 2010/10/21 06:15:28 tteras Exp $	*/
+/*	$NetBSD: session.h,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: session.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */
 
@@ -37,7 +37,4 @@
 extern int session __P((void));
 extern RETSIGTYPE signal_handler __P((int));
 
-extern void monitor_fd __P((int fd, int (*callback)(void *, int), void *ctx, int priority));
-extern void unmonitor_fd __P((int fd));
-
 #endif /* _SESSION_H */
diff --git a/src/racoon/sockmisc.c b/src/racoon/sockmisc.c
index 9301717..e683884 100644
--- a/src/racoon/sockmisc.c
+++ b/src/racoon/sockmisc.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: sockmisc.c,v 1.19 2011/03/14 17:18:13 tteras Exp $	*/
+/*	$NetBSD: sockmisc.c,v 1.8.6.1 2007/08/01 11:52:22 vanhu Exp $	*/
 
 /* Id: sockmisc.c,v 1.24 2006/05/07 21:32:59 manubsd Exp */
 
@@ -56,64 +56,117 @@
 
 #include "var.h"
 #include "misc.h"
-#include "vmbuf.h"
 #include "plog.h"
 #include "sockmisc.h"
 #include "debug.h"
 #include "gcmalloc.h"
 #include "debugrm.h"
 #include "libpfkey.h"
-#include "isakmp_var.h"
 
-#ifdef NOUSE_PRIVSEP
-#define BIND bind
-#define SOCKET socket
-#define SETSOCKOPT setsockopt
-#else
-#include "admin.h"
-#include "privsep.h"
-#define BIND privsep_bind
-#define SOCKET privsep_socket
-#define SETSOCKOPT privsep_setsockopt
+#ifndef IP_IPSEC_POLICY
+#define IP_IPSEC_POLICY 16	/* XXX: from linux/in.h */
+#endif
+
+#ifndef IPV6_IPSEC_POLICY
+#define IPV6_IPSEC_POLICY 34	/* XXX: from linux/???.h per
+				   "Tom Lendacky" <toml@us.ibm.com> */
 #endif
 
 const int niflags = 0;
 
 /*
+ * compare two sockaddr without port number.
+ * OUT:	0: equal.
+ *	1: not equal.
+ */
+int
+cmpsaddrwop(addr1, addr2)
+	const struct sockaddr *addr1;
+	const struct sockaddr *addr2;
+{
+	caddr_t sa1, sa2;
+
+	if (addr1 == 0 && addr2 == 0)
+		return 0;
+	if (addr1 == 0 || addr2 == 0)
+		return 1;
+
+#ifdef __linux__
+	if (addr1->sa_family != addr2->sa_family)
+		return 1;
+#else
+	if (addr1->sa_len != addr2->sa_len
+	 || addr1->sa_family != addr2->sa_family)
+		return 1;
+
+#endif /* __linux__ */
+
+	switch (addr1->sa_family) {
+	case AF_INET:
+		sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr;
+		sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr;
+		if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0)
+			return 1;
+		break;
+#ifdef INET6
+	case AF_INET6:
+		sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr;
+		sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr;
+		if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0)
+			return 1;
+		if (((struct sockaddr_in6 *)addr1)->sin6_scope_id !=
+		    ((struct sockaddr_in6 *)addr2)->sin6_scope_id)
+			return 1;
+		break;
+#endif
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
  * compare two sockaddr with port, taking care wildcard.
  * addr1 is a subject address, addr2 is in a database entry.
  * OUT:	0: equal.
  *	1: not equal.
  */
 int
-cmpsaddr(addr1, addr2)
+cmpsaddrwild(addr1, addr2)
 	const struct sockaddr *addr1;
 	const struct sockaddr *addr2;
 {
 	caddr_t sa1, sa2;
-	u_short port1 = IPSEC_PORT_ANY;
-	u_short port2 = IPSEC_PORT_ANY;
+	u_short port1, port2;
 
-	if (addr1 == NULL && addr2 == NULL)
-		return CMPSADDR_MATCH;
+	if (addr1 == 0 && addr2 == 0)
+		return 0;
+	if (addr1 == 0 || addr2 == 0)
+		return 1;
 
-	if (addr1 == NULL || addr2 == NULL)
-		return CMPSADDR_MISMATCH;
+#ifdef __linux__
+	if (addr1->sa_family != addr2->sa_family)
+		return 1;
+#else
+	if (addr1->sa_len != addr2->sa_len
+	 || addr1->sa_family != addr2->sa_family)
+		return 1;
 
-	if (addr1->sa_family != addr2->sa_family ||
-	    sysdep_sa_len(addr1) != sysdep_sa_len(addr2))
-		return CMPSADDR_MISMATCH;
+#endif /* __linux__ */
 
 	switch (addr1->sa_family) {
-	case AF_UNSPEC:
-		break;
 	case AF_INET:
 		sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr;
 		sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr;
 		port1 = ((struct sockaddr_in *)addr1)->sin_port;
 		port2 = ((struct sockaddr_in *)addr2)->sin_port;
+		if (!(port1 == IPSEC_PORT_ANY ||
+		      port2 == IPSEC_PORT_ANY ||
+		      port1 == port2))
+			return 1;
 		if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0)
-			return CMPSADDR_MISMATCH;
+			return 1;
 		break;
 #ifdef INET6
 	case AF_INET6:
@@ -121,34 +174,92 @@
 		sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr;
 		port1 = ((struct sockaddr_in6 *)addr1)->sin6_port;
 		port2 = ((struct sockaddr_in6 *)addr2)->sin6_port;
+		if (!(port1 == IPSEC_PORT_ANY ||
+		      port2 == IPSEC_PORT_ANY ||
+		      port1 == port2))
+			return 1;
 		if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0)
-			return CMPSADDR_MISMATCH;
+			return 1;
 		if (((struct sockaddr_in6 *)addr1)->sin6_scope_id !=
 		    ((struct sockaddr_in6 *)addr2)->sin6_scope_id)
-			return CMPSADDR_MISMATCH;
+			return 1;
 		break;
 #endif
 	default:
-		return CMPSADDR_MISMATCH;
+		return 1;
 	}
 
-	if (port1 == port2)
-		return CMPSADDR_MATCH;
+	return 0;
+}
 
-	if (port1 == IPSEC_PORT_ANY ||
-	    port2 == IPSEC_PORT_ANY)
-		return CMPSADDR_WILDPORT_MATCH;
+/*
+ * compare two sockaddr with strict match on port.
+ * OUT:	0: equal.
+ *	1: not equal.
+ */
+int
+cmpsaddrstrict(addr1, addr2)
+	const struct sockaddr *addr1;
+	const struct sockaddr *addr2;
+{
+	caddr_t sa1, sa2;
+	u_short port1, port2;
 
-	return CMPSADDR_WOP_MATCH;
+	if (addr1 == 0 && addr2 == 0)
+		return 0;
+	if (addr1 == 0 || addr2 == 0)
+		return 1;
+
+#ifdef __linux__
+	if (addr1->sa_family != addr2->sa_family)
+		return 1;
+#else
+	if (addr1->sa_len != addr2->sa_len
+	 || addr1->sa_family != addr2->sa_family)
+		return 1;
+
+#endif /* __linux__ */
+
+	switch (addr1->sa_family) {
+	case AF_INET:
+		sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr;
+		sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr;
+		port1 = ((struct sockaddr_in *)addr1)->sin_port;
+		port2 = ((struct sockaddr_in *)addr2)->sin_port;
+		if (port1 != port2)
+			return 1;
+		if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0)
+			return 1;
+		break;
+#ifdef INET6
+	case AF_INET6:
+		sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr;
+		sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr;
+		port1 = ((struct sockaddr_in6 *)addr1)->sin6_port;
+		port2 = ((struct sockaddr_in6 *)addr2)->sin6_port;
+		if (port1 != port2)
+			return 1;
+		if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0)
+			return 1;
+		if (((struct sockaddr_in6 *)addr1)->sin6_scope_id !=
+		    ((struct sockaddr_in6 *)addr2)->sin6_scope_id)
+			return 1;
+		break;
+#endif
+	default:
+		return 1;
+	}
+
+	return 0;
 }
 
 #ifdef ANDROID_PATCHED
 
 struct sockaddr *getlocaladdr(struct sockaddr *remote)
-{   
+{
     struct sockaddr_storage local;
     socklen_t len = sysdep_sa_len(remote);
-    int s = privsep_socket(remote->sa_family, SOCK_DGRAM, 0);
+    int s = socket(remote->sa_family, SOCK_DGRAM, 0);
     if (s == -1 || connect(s, remote, len) == -1 ||
         getsockname(s, (struct sockaddr *)&local, &len) == -1) {
         close(s);
@@ -160,7 +271,7 @@
 
 int recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from,
                socklen_t *fromlen, struct sockaddr *to, unsigned int *tolen)
-{   
+{
     if (getsockname(s, to, (socklen_t *)tolen) == -1) {
         return -1;
     }
@@ -169,7 +280,7 @@
 
 int sendfromto(int s, const void *buf, size_t len, struct sockaddr *from,
                struct sockaddr *to, int count)
-{   
+{
     int i;
     for (i = 0; i < count; ++i) {
         if (sendto(s, buf, len, 0, to, sysdep_sa_len(to)) == -1) {
@@ -180,7 +291,7 @@
 }
 
 int setsockopt_bypass(int s, int family)
-{   
+{
     struct sadb_x_policy p = {
         .sadb_x_policy_len = PFKEY_UNIT64(sizeof(struct sadb_x_policy)),
         .sadb_x_policy_exttype = SADB_X_EXT_POLICY,
@@ -224,7 +335,7 @@
 	}
 	
 	/* get real interface received packet */
-	if ((s = SOCKET(remote->sa_family, SOCK_DGRAM, 0)) < 0) {
+	if ((s = socket(remote->sa_family, SOCK_DGRAM, 0)) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"socket (%s)\n", strerror(errno));
 		goto err;
@@ -271,9 +382,8 @@
 	u_int *tolen;
 {
 	int otolen;
-	socklen_t slen;
-	int len;
-	union sockaddr_any sa;
+	u_int len;
+	struct sockaddr_storage ss;
 	struct msghdr m;
 	struct cmsghdr *cm;
 	struct iovec iov[2];
@@ -286,8 +396,8 @@
 	struct sockaddr_in6 *sin6;
 #endif
 
-	slen = sizeof(sa);
-	if (getsockname(s, &sa.sa, &slen) < 0) {
+	len = sizeof(ss);
+	if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"getsockname (%s)\n", strerror(errno));
 		return -1;
@@ -320,7 +430,7 @@
 			"cmsg %d %d\n", cm->cmsg_level, cm->cmsg_type);)
 #endif
 #if defined(INET6) && defined(INET6_ADVAPI)
-		if (sa.sa.sa_family == AF_INET6
+		if (ss.ss_family == AF_INET6
 		 && cm->cmsg_level == IPPROTO_IPV6
 		 && cm->cmsg_type == IPV6_PKTINFO
 		 && otolen >= sizeof(*sin6)) {
@@ -339,13 +449,14 @@
 				sin6->sin6_scope_id = pi->ipi6_ifindex;
 			else
 				sin6->sin6_scope_id = 0;
-			sin6->sin6_port = sa.sin6.sin6_port;
+			sin6->sin6_port =
+				((struct sockaddr_in6 *)&ss)->sin6_port;
 			otolen = -1;	/* "to" already set */
 			continue;
 		}
 #endif
 #ifdef __linux__
-		if (sa.sa.sa_family == AF_INET
+		if (ss.ss_family == AF_INET
 		 && cm->cmsg_level == IPPROTO_IP
 		 && cm->cmsg_type == IP_PKTINFO
 		 && otolen >= sizeof(sin)) {
@@ -356,13 +467,14 @@
 			sin->sin_family = AF_INET;
 			memcpy(&sin->sin_addr, &pi->ipi_addr,
 				sizeof(sin->sin_addr));
-			sin->sin_port = sa.sin.sin_port;
+			sin->sin_port =
+				((struct sockaddr_in *)&ss)->sin_port;
 			otolen = -1;	/* "to" already set */
 			continue;
 		}
 #endif
 #if defined(INET6) && defined(IPV6_RECVDSTADDR)
-		if (sa.sa.sa_family == AF_INET6
+		if (ss.ss_family == AF_INET6
 		      && cm->cmsg_level == IPPROTO_IPV6
 		      && cm->cmsg_type == IPV6_RECVDSTADDR
 		      && otolen >= sizeof(*sin6)) {
@@ -373,13 +485,14 @@
 			sin6->sin6_len = sizeof(*sin6);
 			memcpy(&sin6->sin6_addr, CMSG_DATA(cm),
 				sizeof(sin6->sin6_addr));
-			sin6->sin6_port = sa.sin6.sin6_port;
+			sin6->sin6_port =
+				((struct sockaddr_in6 *)&ss)->sin6_port;
 			otolen = -1;	/* "to" already set */
 			continue;
 		}
 #endif
 #ifndef __linux__
-		if (sa.sa.sa_family == AF_INET
+		if (ss.ss_family == AF_INET
 		 && cm->cmsg_level == IPPROTO_IP
 		 && cm->cmsg_type == IP_RECVDSTADDR
 		 && otolen >= sizeof(*sin)) {
@@ -390,7 +503,7 @@
 			sin->sin_len = sizeof(*sin);
 			memcpy(&sin->sin_addr, CMSG_DATA(cm),
 				sizeof(sin->sin_addr));
-			sin->sin_port = sa.sin.sin_port;
+			sin->sin_port = ((struct sockaddr_in *)&ss)->sin_port;
 			otolen = -1;	/* "to" already set */
 			continue;
 		}
@@ -410,8 +523,7 @@
 	struct sockaddr *dst;
 {
 	struct sockaddr_storage ss;
-	socklen_t slen;
-	int len = 0;
+	u_int len;
 	int i;
 
 	if (src->sa_family != dst->sa_family) {
@@ -420,8 +532,8 @@
 		return -1;
 	}
 
-	slen = sizeof(ss);
-	if (getsockname(s, (struct sockaddr *)&ss, &slen) < 0) {
+	len = sizeof(ss);
+	if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) {
 		plog(LLV_ERROR, LOCATION, NULL,
 			"getsockname (%s)\n", strerror(errno));
 		return -1;
@@ -589,7 +701,7 @@
 			 * Better approach is to prepare bind'ed udp sockets for
 			 * each of the interface addresses.
 			 */
-			sendsock = SOCKET(src->sa_family, SOCK_DGRAM, 0);
+			sendsock = socket(src->sa_family, SOCK_DGRAM, 0);
 			if (sendsock < 0) {
 				plog(LLV_ERROR, LOCATION, NULL,
 					"socket (%s)\n", strerror(errno));
@@ -624,8 +736,7 @@
 				return -1;
 			}
 
-			if (BIND(sendsock, (struct sockaddr *)src,
-				 sysdep_sa_len(src)) < 0) {
+			if (bind(sendsock, (struct sockaddr *)src, sysdep_sa_len(src)) < 0) {
 				plog(LLV_ERROR, LOCATION, NULL,
 					"bind 1 (%s)\n", strerror(errno));
 				close(sendsock);
@@ -689,7 +800,7 @@
 			ipsec_strerror());
 		return -1;
 	}
-	if (SETSOCKOPT(so, level,
+	if (setsockopt(so, level,
 	               (level == IPPROTO_IP ?
 	                         IP_IPSEC_POLICY : IPV6_IPSEC_POLICY),
 	               buf, ipsec_get_policylen(buf)) < 0) {
@@ -708,7 +819,7 @@
 			ipsec_strerror());
 		return -1;
 	}
-	if (SETSOCKOPT(so, level,
+	if (setsockopt(so, level,
 	               (level == IPPROTO_IP ?
 	                         IP_IPSEC_POLICY : IPV6_IPSEC_POLICY),
 	               buf, ipsec_get_policylen(buf)) < 0) {
@@ -722,8 +833,6 @@
 	return 0;
 }
 
-#endif
-
 struct sockaddr *
 newsaddr(len)
 	int len;
@@ -749,6 +858,8 @@
 	return new;
 }
 
+#endif
+
 struct sockaddr *
 dupsaddr(src)
 	struct sockaddr *src;
@@ -1003,13 +1114,13 @@
 		free(a2);
 		free(a3);
 	}
-	if (cmpsaddr(&sa, &naddr->sa.sa) <= CMPSADDR_WOP_MATCH)
+	if (cmpsaddrwop(&sa, &naddr->sa.sa) == 0)
 		return naddr->prefix + port_score;
 
 	return -1;
 }
 
-/* Some useful functions for sockaddr port manipulations. */
+/* Some usefull functions for sockaddr port manipulations. */
 u_int16_t
 extract_port (const struct sockaddr *addr)
 {
@@ -1019,8 +1130,6 @@
     return port;
 
   switch (addr->sa_family) {
-    case AF_UNSPEC:
-      break;
     case AF_INET:
       port = ((struct sockaddr_in *)addr)->sin_port;
       break;
diff --git a/src/racoon/sockmisc.h b/src/racoon/sockmisc.h
index 67bfdaf..a035dec 100644
--- a/src/racoon/sockmisc.h
+++ b/src/racoon/sockmisc.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: sockmisc.h,v 1.13 2011/03/14 17:18:13 tteras Exp $	*/
+/*	$NetBSD: sockmisc.h,v 1.7 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: sockmisc.h,v 1.9 2005/10/05 16:55:41 manubsd Exp */
 
@@ -34,34 +34,26 @@
 #ifndef _SOCKMISC_H
 #define _SOCKMISC_H
 
-#ifndef IP_IPSEC_POLICY
-#define IP_IPSEC_POLICY 16	/* XXX: from linux/in.h */
-#endif
-
-#ifndef IPV6_IPSEC_POLICY
-#define IPV6_IPSEC_POLICY 34	/* XXX: from linux/???.h per
-				   "Tom Lendacky" <toml@us.ibm.com> */
-#endif
-
-union sockaddr_any {
-	struct sockaddr sa;
-	struct sockaddr_in sin;
-	struct sockaddr_in6 sin6;
-};
-
 struct netaddr {
-	union sockaddr_any sa;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa;
 	unsigned long prefix;
 };
 
 extern const int niflags;
 
-#define CMPSADDR_MATCH		0
-#define CMPSADDR_WILDPORT_MATCH	1
-#define CMPSADDR_WOP_MATCH	2
-#define CMPSADDR_MISMATCH	3
+extern int cmpsaddrwop __P((const struct sockaddr *, const struct sockaddr *));
+extern int cmpsaddrwild __P((const struct sockaddr *, const struct sockaddr *));
+extern int cmpsaddrstrict __P((const struct sockaddr *, const struct sockaddr *));
 
-extern int cmpsaddr __P((const struct sockaddr *, const struct sockaddr *));
+#ifdef ENABLE_NATT 
+#define CMPSADDR(saddr1, saddr2) cmpsaddrstrict((saddr1), (saddr2))
+#else 
+#define CMPSADDR(saddr1, saddr2) cmpsaddrwop((saddr1), (saddr2))
+#endif
 
 extern struct sockaddr *getlocaladdr __P((struct sockaddr *));
 
@@ -89,7 +81,7 @@
 				      const struct netaddr *daddr));
 extern int naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr);
 
-/* Some useful functions for sockaddr port manipulations. */
+/* Some usefull functions for sockaddr port manipulations. */
 extern u_int16_t extract_port __P((const struct sockaddr *addr));
 extern u_int16_t *set_port __P((struct sockaddr *addr, u_int16_t new_port));
 extern u_int16_t *get_port_ptr __P((struct sockaddr *addr));
diff --git a/src/racoon/strnames.c b/src/racoon/strnames.c
index 4906b33..fa5df0f 100644
--- a/src/racoon/strnames.c
+++ b/src/racoon/strnames.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: strnames.c,v 1.9 2008/07/14 05:40:13 tteras Exp $	*/
+/*	$NetBSD: strnames.c,v 1.7.6.1 2007/08/01 11:52:22 vanhu Exp $	*/
 
 /*	$KAME: strnames.c,v 1.25 2003/11/13 10:53:26 itojun Exp $	*/
 
@@ -276,8 +276,6 @@
 { ISAKMP_NTYPE_RESPONDER_LIFETIME,	"RESPONDER-LIFETIME",		NULL },
 { ISAKMP_NTYPE_REPLAY_STATUS,		"REPLAY-STATUS",		NULL },
 { ISAKMP_NTYPE_INITIAL_CONTACT,		"INITIAL-CONTACT",		NULL },
-{ ISAKMP_NTYPE_R_U_THERE,		"R-U-THERE",			NULL },
-{ ISAKMP_NTYPE_R_U_THERE_ACK,		"R-U-THERE-ACK",		NULL },
 #ifdef ENABLE_HYBRID
 { ISAKMP_NTYPE_UNITY_HEARTBEAT,		"HEARTBEAT (Unity)",		NULL },
 #endif
diff --git a/src/racoon/throttle.c b/src/racoon/throttle.c
index 84a2d6b..cd7de1f 100644
--- a/src/racoon/throttle.c
+++ b/src/racoon/throttle.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: throttle.c,v 1.7 2011/03/14 17:18:13 tteras Exp $	*/
+/*	$NetBSD: throttle.c,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: throttle.c,v 1.5 2006/04/05 20:54:50 manubsd Exp */
 
@@ -33,10 +33,23 @@
 
 #include "config.h"
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h> 
+#else 
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif 
+#endif
 #include <sys/param.h>
 #include <sys/queue.h>
+#include <sys/socket.h>
+
 #include <netinet/in.h>
 #include <resolv.h>
 
@@ -45,21 +58,21 @@
 #include "plog.h"
 #include "throttle.h"
 #include "sockmisc.h"
+#include "libpfkey.h"
 #include "isakmp_var.h"
 #include "isakmp.h"
 #include "isakmp_xauth.h"
 #include "isakmp_cfg.h"
 #include "gcmalloc.h"
 
-static struct throttle_list throttle_list =
-	TAILQ_HEAD_INITIALIZER(throttle_list);
+struct throttle_list throttle_list = TAILQ_HEAD_INITIALIZER(throttle_list);
+
 
 struct throttle_entry *
 throttle_add(addr)
 	struct sockaddr *addr;
 {
 	struct throttle_entry *te;
-	struct timeval now, penalty;
 	size_t len;
 
 	len = sizeof(*te) 
@@ -69,11 +82,7 @@
 	if ((te = racoon_malloc(len)) == NULL)
 		return NULL;
 
-	sched_get_monotonic_time(&now);
-	penalty.tv_sec = isakmp_cfg_config.auth_throttle;
-	penalty.tv_usec = 0;
-	timeradd(&now, &penalty, &te->penalty_ends);
-
+	te->penalty = time(NULL) + isakmp_cfg_config.auth_throttle;
 	memcpy(&te->host, addr, sysdep_sa_len(addr));
 	TAILQ_INSERT_HEAD(&throttle_list, te, next);
 
@@ -86,25 +95,26 @@
 	int authfail;
 {
 	struct throttle_entry *te;
-	struct timeval now, res;
 	int found = 0;
+	time_t now;
 
 	if (isakmp_cfg_config.auth_throttle == 0)
 		return 0;
 
-	sched_get_monotonic_time(&now);
+	now = time(NULL);
+
 restart:
 	RACOON_TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) {
-		/*
-		 * Remove outdated entries
-		 */
-		if (timercmp(&te->penalty_ends, &now, <)) {
+	  /*
+	   * Remove outdated entries 
+	   */
+		if (te->penalty < now) {
 			TAILQ_REMOVE(&throttle_list, te, next);
 			racoon_free(te);
 			goto restart;
 		}
-
-		if (cmpsaddr(addr, (struct sockaddr *) &te->host) <= CMPSADDR_WOP_MATCH) {
+			
+		if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) {
 			found = 1;
 			break;
 		}
@@ -120,7 +130,8 @@
 			if ((te = throttle_add(addr)) == NULL) {
 				plog(LLV_ERROR, LOCATION, NULL, 
 				    "Throttle insertion failed\n");
-				return isakmp_cfg_config.auth_throttle;
+				return (time(NULL) 
+				    + isakmp_cfg_config.auth_throttle);
 			}
 		}
 		return 0;
@@ -129,21 +140,19 @@
 		 * We had a match and auth failed, increase penalty.
 		 */
 		if (authfail) {
-			struct timeval remaining, penalty;
+			time_t remaining;
+			time_t new;
 
-			timersub(&te->penalty_ends, &now, &remaining);
-			penalty.tv_sec = isakmp_cfg_config.auth_throttle;
-			penalty.tv_usec = 0;
-			timeradd(&penalty, &remaining, &res);
-			if (res.tv_sec >= THROTTLE_PENALTY_MAX) {
-				res.tv_sec = THROTTLE_PENALTY_MAX;
-				res.tv_usec = 0;
-			}
-			timeradd(&now, &res, &te->penalty_ends);
+			remaining = te->penalty - now;
+			new = remaining + isakmp_cfg_config.auth_throttle;
+
+			if (new > THROTTLE_PENALTY_MAX)
+				new = THROTTLE_PENALTY_MAX;
+
+			te->penalty = now + new;
 		}
 	}
-
-	timersub(&te->penalty_ends, &now, &res);
-	return res.tv_sec;
+	
+	return te->penalty;
 }
 
diff --git a/src/racoon/throttle.h b/src/racoon/throttle.h
index 54a8ed1..baa9af5 100644
--- a/src/racoon/throttle.h
+++ b/src/racoon/throttle.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: throttle.h,v 1.5 2009/01/23 08:25:07 tteras Exp $	*/
+/*	$NetBSD: throttle.h,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: throttle.h,v 1.1 2004/11/30 00:46:09 manubsd Exp */
 
@@ -34,10 +34,8 @@
 #ifndef _THROTTLE_H
 #define _THROTTLE_H
 
-#include "schedule.h"
-
 struct throttle_entry {
-	struct timeval penalty_ends;
+	int penalty;
 	TAILQ_ENTRY(throttle_entry) next;
 	struct sockaddr_storage host;
 };
diff --git a/src/racoon/var.h b/src/racoon/var.h
index 2946a9f..8abb1c2 100644
--- a/src/racoon/var.h
+++ b/src/racoon/var.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.h,v 1.5 2007/06/06 15:37:15 vanhu Exp $	*/
+/*	$NetBSD: var.h,v 1.4.6.1 2007/06/06 15:36:38 vanhu Exp $	*/
 
 /* Id: var.h,v 1.6 2004/11/20 16:16:59 monas Exp */
 
diff --git a/src/racoon/vendorid.c b/src/racoon/vendorid.c
index 81297bd..82ddfe4 100644
--- a/src/racoon/vendorid.c
+++ b/src/racoon/vendorid.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: vendorid.c,v 1.8 2009/09/01 12:22:09 tteras Exp $	*/
+/*	$NetBSD: vendorid.c,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: vendorid.c,v 1.10 2006/02/22 16:10:21 vanhu Exp */
 
@@ -53,16 +53,6 @@
 #include "isakmp.h"
 #include "vendorid.h"
 #include "crypto_openssl.h"
-#include "handler.h"
-#include "remoteconf.h"
-#ifdef ENABLE_NATT
-#include "nattraversal.h"
-#endif
-#ifdef ENABLE_HYBRID
-#include <resolv.h>
-#include "isakmp_xauth.h"
-#include "isakmp_cfg.h"
-#endif
 
 static struct vendor_id all_vendor_ids[] = {
 { VENDORID_IPSEC_TOOLS, "IPSec-Tools" },
@@ -215,7 +205,7 @@
  *
  * gen ... points to Vendor ID payload.
  */
-static int
+int
 check_vendorid(struct isakmp_gen *gen)
 {
 	vchar_t vid, *vidhash;
@@ -248,44 +238,6 @@
 	return (VENDORID_UNKNOWN);
 }
 
-int
-handle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen)
-{
-	int vid_numeric;
-
-	vid_numeric = check_vendorid(gen);
-	if (vid_numeric == VENDORID_UNKNOWN)
-		return vid_numeric;
-
-	iph1->vendorid_mask |= BIT(vid_numeric);
-
-#ifdef ENABLE_NATT
-	if (natt_vendorid(vid_numeric))
-		natt_handle_vendorid(iph1, vid_numeric);
-#endif
-#ifdef ENABLE_HYBRID
-	switch (vid_numeric) {
-	case VENDORID_XAUTH:
-		iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_XAUTH;
-		break;
-	case VENDORID_UNITY:
-		iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_UNITY;
-		break;
-	default:
-		break;
-	}
-#endif
-#ifdef ENABLE_DPD
-	if (vid_numeric == VENDORID_DPD &&
-	    (iph1->rmconf == NULL || iph1->rmconf->dpd)) {
-		iph1->dpd_support = 1;
-		plog(LLV_DEBUG, LOCATION, NULL, "remote supports DPD\n");
-	}
-#endif
-
-	return vid_numeric;
-}
-
 static vchar_t * 
 vendorid_fixup(vendorid, vidhash)
 	int vendorid;		 
diff --git a/src/racoon/vendorid.h b/src/racoon/vendorid.h
index 1774575..7e2dcda 100644
--- a/src/racoon/vendorid.h
+++ b/src/racoon/vendorid.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: vendorid.h,v 1.6 2009/01/23 08:06:56 tteras Exp $	*/
+/*	$NetBSD: vendorid.h,v 1.4 2006/09/09 16:22:10 manu Exp $	*/
 
 /* Id: vendorid.h,v 1.11 2006/02/17 14:09:10 vanhu Exp */
 
@@ -34,26 +34,25 @@
 #ifndef _VENDORID_H
 #define _VENDORID_H
 
-#ifndef BIT
-#define BIT(x) (1 << (x))
-#endif
-
 /* The unknown vendor ID. */
-#define VENDORID_UNKNOWN	-1
+#define	VENDORID_UNKNOWN	-1
+
 
 /* Our default vendor ID. */
-#define VENDORID_DEFAULT	VENDORID_IPSEC_TOOLS
+#define	VENDORID_DEFAULT	VENDORID_IPSEC_TOOLS
 
-#define VENDORID_IPSEC_TOOLS	0
+#define	VENDORID_IPSEC_TOOLS 0		
 
-/* Refer to draft-ietf-ipsec-isakmp-gss-auth-06.txt. */
-#define VENDORID_GSSAPI_LONG	1
-#define VENDORID_GSSAPI		2
-#define VENDORID_MS_NT5		3
-
-#define VENDORID_GSSAPI_MASK	(BIT(VENDORID_GSSAPI_LONG) | \
-				 BIT(VENDORID_GSSAPI) | \
-				 BIT(VENDORID_MS_NT5))
+/*
+ * Refer to draft-ietf-ipsec-isakmp-gss-auth-06.txt.
+ */
+#define	VENDORID_GSSAPI_LONG	1
+#define	VENDORID_GSSAPI		2
+#define	VENDORID_MS_NT5		3
+#define	VENDOR_SUPPORTS_GSSAPI(x)					\
+	((x) == VENDORID_GSSAPI_LONG ||					\
+	 (x) == VENDORID_GSSAPI ||					\
+	 (x) == VENDORID_MS_NT5)
 
 /* NAT-T support */
 #define VENDORID_NATT_00	4
@@ -71,7 +70,8 @@
 #define VENDORID_NATT_FIRST	VENDORID_NATT_00
 #define VENDORID_NATT_LAST	VENDORID_NATT_RFC
 
-#define MAX_NATT_VID_COUNT	(VENDORID_NATT_LAST - VENDORID_NATT_FIRST + 1)
+
+#define MAX_NATT_VID_COUNT	(VENDORID_NATT_LAST - VENDORID_NATT_FIRST + 1 )
 
 /* Hybrid auth */
 #define VENDORID_XAUTH		15
@@ -88,7 +88,8 @@
  * XXX: do some cleanup to have separate lists for "real" vendors (to complete)
  * and "features" VendorIDs
  */
-#define VENDORID_KAME		19
+#define	VENDORID_KAME		19
+
 
 struct vendor_id {
 	int		id;
@@ -97,7 +98,7 @@
 };
 
 vchar_t *set_vendorid __P((int));
-int handle_vendorid __P((struct ph1handle *, struct isakmp_gen *));
+int check_vendorid __P((struct isakmp_gen *));
 
 void compute_vendorids __P((void));
 const char *vid_string_by_id __P((int id));