]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/isakmp.c
ipsec-258.1.3.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp.c
index 16eabb321eaae0a6bdbec28ad1afb40c354e43ae..324b06491061273bb748e26d3a5caea95871163f 100644 (file)
 #include "sockmisc.h"
 #include "schedule.h"
 #include "debug.h"
+#include "session.h"
+#include "fsm.h"
 
 #include "remoteconf.h"
 #include "localconf.h"
 #include "grabmyaddr.h"
-#include "admin.h"
-#include "privsep.h"
 #include "isakmp_var.h"
 #include "isakmp.h"
 #include "oakley.h"
-#include "evt.h"
 #include "handler.h"
 #include "proposal.h"
 #include "ipsec_doi.h"
 #include "policy.h"
 #include "isakmp_ident.h"
 #include "isakmp_agg.h"
-#include "isakmp_base.h"
 #include "isakmp_quick.h"
 #include "isakmp_inf.h"
-#include "isakmp_newg.h"
 #include "vpn_control.h"
 #include "vpn_control_var.h"
 #ifdef ENABLE_HYBRID
 #include "ipsecMessageTracer.h"
 #include "power_mgmt.h"
 
-static int nostate1 __P((struct ph1handle *, vchar_t *));
-static int nostate2 __P((struct ph2handle *, vchar_t *));
-
-extern caddr_t val2str(const char *, size_t);
-
-static int (*ph1exchange[][2][PHASE1ST_MAX])
-       __P((struct ph1handle *, vchar_t *)) = {
- /* error */
- { {}, {}, },
- /* Identity Protection exchange */
- {
-  { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send,
-    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, },
- },
- /* Aggressive exchange */
- {
-  { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send,
-    nostate1, nostate1, nostate1, nostate1, nostate1, },
-  { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send,
-    nostate1, nostate1, nostate1, nostate1, nostate1, },
- },
- /* Base exchange */
- {
-  { nostate1, base_i1send, nostate1, base_i2recv, base_i2send,
-    base_i3recv, base_i3send, nostate1, nostate1, nostate1, },
-  { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send,
-    nostate1, nostate1, nostate1, nostate1, nostate1, },
- },
-};
-
-static int (*ph2exchange[][2][PHASE2ST_MAX])
-       __P((struct ph2handle *, vchar_t *)) = {
- /* error */
- { {}, {}, },
- /* Quick mode for IKE */
- {
-  { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send,
-    quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, },
-  { nostate2, quick_r1recv, quick_r1prep, nostate2, quick_r2send,
-    quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, }
- },
-};
-
-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_storage *, struct sockaddr_storage *));
-static int ph1_main __P((struct ph1handle *, vchar_t *));
-static int quick_main __P((struct ph2handle *, vchar_t *));
-static int isakmp_ph1begin_r __P((vchar_t *,
-       struct sockaddr_storage *, struct sockaddr_storage *, u_int8_t));
-static int isakmp_ph2begin_i __P((struct ph1handle *, struct ph2handle *));
-static int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *));
-static int etypesw1 __P((int));
-static int etypesw2 __P((int));
+
+extern caddr_t val2str (const char *, size_t);
+u_char i_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the i_ck. */
+u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
+
+
+static void isakmp_main (vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
+static void ikev1_received_packet(vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
+static int ikev1_ph1begin_r (ike_session_t *session, vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *, u_int8_t);
+static int ikev1_ph2begin_i (phase1_handle_t *, phase2_handle_t *);
+static int ikev1_ph2begin_r (phase1_handle_t *, vchar_t *);
+
+
 #ifdef ENABLE_FRAG
-static int frag_handler(struct ph1handle *, 
-    vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
+static void frag_handler (phase1_handle_t *, vchar_t *, struct sockaddr_storage *, struct sockaddr_storage *);
 #endif
 
 /*
  * isakmp packet handler
  */
-int
-isakmp_handler(so_isakmp)
-       int so_isakmp;
+void
+isakmp_handler(int so_isakmp)
 {
        struct isakmp isakmp;
        union {
@@ -219,9 +171,9 @@ isakmp_handler(so_isakmp)
        int error = -1;
 
        if (slept_at || woke_at) {
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG, 
                         "ignoring isakmp port until power-mgmt event is handled.\n");
-               return 0;
+               return;
        }
 
        /* read message by MSG_PEEK */
@@ -229,7 +181,7 @@ isakmp_handler(so_isakmp)
                    MSG_PEEK, &remote, &remote_len, &local, &local_len)) < 0) {
                if (errno == EINTR)
                        continue;
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to receive isakmp packet: %s\n",
                        strerror (errno));
                goto end;
@@ -240,31 +192,18 @@ isakmp_handler(so_isakmp)
                /* Pull the keep-alive packet */
                if ((len = recvfrom(so_isakmp, (char *)x.buf, 1,
                    0, (struct sockaddr *)&remote, &remote_len)) != 1) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                            "failed to receive keep alive packet: %s\n",
                            strerror (errno));
         }
                goto end;
        }
 
-       /* Lucent IKE in UDP encapsulation */
-       {
-               struct udphdr *udp;
-               struct ip *ip;
 
-               udp = ALIGNED_CAST(struct udphdr *)&x.lbuf[0];
-               if (ntohs(udp->uh_dport) == 501) {
-                       ip = ALIGNED_CAST(struct ip *)(x.lbuf + sizeof(*udp));
-                       extralen += sizeof(*udp) + ip->ip_hl;
-               }
-       }       
-
-#ifdef ENABLE_NATT
        /* 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 
           marker at the beginning or not */
@@ -272,13 +211,12 @@ isakmp_handler(so_isakmp)
 
        /* check isakmp header length, as well as sanity of header length */
        if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) {
-               plog(LLV_ERROR, LOCATION, &remote,
-                       "packet shorter than isakmp header size (%u, %u, %zu)\n",
-                       len, ntohl(isakmp.len), sizeof(isakmp));
+               plog(ASL_LEVEL_ERR,
+                       "packet shorter than isakmp header size (size: %zu, minimum expected: %zu)\n", len, sizeof(isakmp));
                /* dummy receive */
                if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
                            0, (struct sockaddr *)&remote, &remote_len)) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "failed to receive isakmp packet: %s\n",
                                strerror (errno));
                }
@@ -287,11 +225,11 @@ isakmp_handler(so_isakmp)
 
        /* reject it if the size is tooooo big. */
        if (ntohl(isakmp.len) > 0xffff) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "the length in the isakmp header is too big.\n");
                if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
                            0, (struct sockaddr *)&remote, &remote_len)) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "failed to receive isakmp packet: %s\n",
                                strerror (errno));
                }
@@ -300,13 +238,13 @@ isakmp_handler(so_isakmp)
 
        /* read real message */
        if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to allocate reading buffer (%u Bytes)\n",
                        ntohl(isakmp.len) + extralen);
                /* dummy receive */
                if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
                            0, (struct sockaddr *)&remote, &remote_len)) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "failed to receive isakmp packet: %s\n", 
                                strerror (errno));
                                error = -2;    /* serious problem with socket */
@@ -318,22 +256,22 @@ isakmp_handler(so_isakmp)
                            0, &remote, &remote_len, &local, &local_len)) < 0) {
                if (errno == EINTR)
                        continue;
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to receive isakmp packet: %s\n",
                        strerror (errno));
                goto end;
        }
 
        if (len < extralen) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "invalid len (%d Bytes) & extralen (%d Bytes)\n",
+               plog(ASL_LEVEL_ERR, 
+                        "invalid len (%zd Bytes) & extralen (%d Bytes)\n",
                         len, extralen);
                goto end;
        }
 
        if ((buf = vmalloc(len - extralen)) == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "failed to allocate reading buffer (%u Bytes)\n",
+               plog(ASL_LEVEL_ERR, 
+                       "failed to allocate reading buffer (%lu Bytes)\n",
                        (len - extralen));
                goto end;
        }
@@ -343,18 +281,15 @@ isakmp_handler(so_isakmp)
        len -= extralen;
        
        if (len != buf->l) {
-               plog(LLV_ERROR, LOCATION, &remote, "received invalid length (%d != %zu), why ?\n",
+               plog(ASL_LEVEL_ERR, "received invalid length (%zd != %zu), why ?\n",
                        len, buf->l);
                goto end;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
-       plog(LLV_DEBUG, LOCATION, NULL,
-               "%d bytes message received %s\n",
-               len, saddr2str_fromto("from %s to %s", 
-                       (struct sockaddr *)&remote,
-                       (struct sockaddr *)&local));
-       plogdump(LLV_DEBUG, buf->v, buf->l);
+       plog(ASL_LEVEL_DEBUG, "%zd bytes message received %s\n",
+                        len, saddr2str_fromto("from %s to %s", 
+                                                                  (struct sockaddr *)&remote,
+                                                                  (struct sockaddr *)&local));
 
        /* avoid packets with malicious port/address */
        switch (remote.ss_family) {
@@ -367,12 +302,12 @@ isakmp_handler(so_isakmp)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "invalid family: %d\n", remote.ss_family);
                goto end;
        }
        if (port == 0) {
-               plog(LLV_ERROR, LOCATION, &remote,
+               plog(ASL_LEVEL_ERR,
                        "src port == 0 (valid as UDP but not with IKE)\n");
                goto end;
        }
@@ -382,11 +317,12 @@ isakmp_handler(so_isakmp)
        /* XXX: I don't know how to check isakmp half connection attack. */
 
        /* simply reply if the packet was processed. */
-       if (check_recvdpkt(&remote, &local, buf)) {
+
+       if (ike_session_check_recvdpkt(&remote, &local, buf)) {
                IPSECLOGASLMSG("Received retransmitted packet from %s.\n",
                                           saddr2str((struct sockaddr *)&remote));
 
-               plog(LLV_NOTIFY, LOCATION, NULL,
+               plog(ASL_LEVEL_NOTICE, 
                        "the packet is retransmitted by %s.\n",
                        saddr2str((struct sockaddr *)&remote));
                error = 0;
@@ -394,9 +330,7 @@ isakmp_handler(so_isakmp)
        }
 
        /* isakmp main routine */
-       if (isakmp_main(buf, &remote, &local) != 0) goto end;
-
-       error = 0;
+       isakmp_main(buf, &remote, &local);
 
 end:
        if (tmpbuf != NULL)
@@ -404,21 +338,17 @@ end:
        if (buf != NULL)
                vfree(buf);
 
-       return(error);
+       return;
 }
 
 /*
  * main processing to handle isakmp payload
  */
-static int
-isakmp_main(msg, remote, local)
-       vchar_t *msg;
-       struct sockaddr_storage *remote, *local;
+static void
+isakmp_main(vchar_t *msg, struct sockaddr_storage *remote,  struct sockaddr_storage *local)
 {
        struct isakmp *isakmp = (struct isakmp *)msg->v;
-       isakmp_index *index = (isakmp_index *)isakmp;
-       u_int32_t msgid = isakmp->msgid;
-       struct ph1handle *iph1;
+    u_int8_t isakmp_version = isakmp->v;
 
 #ifdef HAVE_PRINT_ISAKMP_C
        isakmp_printpacket(msg, remote, local, 0);
@@ -426,9 +356,9 @@ isakmp_main(msg, remote, local)
 
        /* the initiator's cookie must not be zero */
        if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) {
-               plog(LLV_ERROR, LOCATION, remote,
+               plog(ASL_LEVEL_ERR, 
                        "malformed cookie received.\n");
-               return -1;
+               return;
        }
 
        /* Check the Major and Minor Version fields. */
@@ -437,64 +367,87 @@ isakmp_main(msg, remote, local)
         * I think it may no be here because the version depends
         * on exchange status.
         */
-       if (isakmp->v < ISAKMP_VERSION_NUMBER) {
-               if (ISAKMP_GETMAJORV(isakmp->v) < ISAKMP_MAJOR_VERSION) {
-                       plog(LLV_ERROR, LOCATION, remote,
-                               "invalid major version %d.\n",
-                               ISAKMP_GETMAJORV(isakmp->v));
-                       return -1;
-               }
-#if ISAKMP_MINOR_VERSION > 0
-               if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) {
-                       plog(LLV_ERROR, LOCATION, remote,
+       if (ISAKMP_GETMAJORV(isakmp_version) != ISAKMP_MAJOR_VERSION_IKEV1 &&
+        ISAKMP_GETMAJORV(isakmp_version) != ISAKMP_MAJOR_VERSION_IKEV2) {        
+                       plog(ASL_LEVEL_ERR, "invalid major version %d.\n", isakmp_version);
+                       return;
+    }
+
+#if 0
+#if ISAKMP_MINOR_VERSION > 0        //%%%%%%%% fix this
+               if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) {   //%%%%%%%%%%%%%%% ??????
+                       plog(ASL_LEVEL_ERR,
                                "invalid minor version %d.\n",
                                ISAKMP_GETMINORV(isakmp->v));
-                       return -1;
+                       return;
                }
 #endif
-       }
+#endif
 
-       /* check the Flags field. */
-       /* XXX How is the exclusive check, E and A ? */
-       if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) {
-               plog(LLV_ERROR, LOCATION, remote,
-                       "invalid flag 0x%02x.\n", isakmp->flags);
-               return -1;
-       }
+    if (isakmp_version == ISAKMP_VERSION_NUMBER_IKEV1) {
+               /* check the Flags field. */
+               /* XXX How is the exclusive check, E and A ? */
+               if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) { //%%%%%%%%%%%% any other flags for IKEv2 ?????
+                       plog(ASL_LEVEL_ERR, "invalid flag 0x%02x.\n", isakmp->flags);
+                       return;
+               }
 
-       /* ignore commit bit. */
-       if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) {
-               if (isakmp->msgid == 0) {
-                       isakmp_info_send_nx(isakmp, remote, local,
-                               ISAKMP_NTYPE_INVALID_FLAGS, NULL);
-                       plog(LLV_ERROR, LOCATION, remote,
-                               "Commit bit on phase1 forbidden.\n");
-                       return -1;
+               /* ignore commit bit. */
+               if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) {
+                       if (isakmp->msgid == 0) {                   //%%%%% does this apply to V2
+                               isakmp_info_send_nx(isakmp, remote, local,
+                                                                       ISAKMP_NTYPE_INVALID_FLAGS, NULL);
+                               plog(ASL_LEVEL_ERR, "Commit bit on Phase 1 forbidden.\n");
+                               return;
+                       }
                }
+
+        ikev1_received_packet(msg, local, remote);
        }
+    return;
+}
 
-       iph1 = getph1byindex(index);
+/*
+ * ikev1_received_packet
+ * Handler for received IKEv1 Packets
+ */
+static void
+ikev1_received_packet(vchar_t *msg, struct sockaddr_storage *local, struct sockaddr_storage *remote)
+{
+    ike_session_t       *session;
+    phase1_handle_t     *iph1;
+    
+    struct isakmp *isakmp = (struct isakmp *)msg->v;
+    isakmp_index *index = (isakmp_index *)isakmp;
+    
+    session = ike_session_get_session(local, remote, 1);
+    if (!session) {
+        plog (ASL_LEVEL_INFO, "failed to allocate or find ike session.\n");
+        fatal_error(-1);
+    }
+        
+       iph1 = ike_session_getph1byindex(session, index);
        if (iph1 != NULL) {
                /* validity check */
                if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
                    iph1->side == INITIATOR) {
                        IPSECSESSIONTRACEREVENT(iph1->parent_session,
                                                                        IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
-                                                                       CONSTSTR("malformed or unexpected cookie"),
+                                                                       CONSTSTR("Malformed or unexpected cookie"),
                                                                        CONSTSTR("Failed to process packet (malformed/unexpected cookie)"));
-                       plog(LLV_DEBUG, LOCATION, remote,
-                               "malformed cookie received or "
+                       plog(ASL_LEVEL_DEBUG, 
+                               "Malformed cookie received or "
                                "the initiator's cookies collide.\n");
-                       return -1;
+                       return;
                }
-
-#ifdef ENABLE_NATT
+        
+        
                /* Floating ports for NAT-T */
                if (NATT_AVAILABLE(iph1) &&
                    ! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
                    ((cmpsaddrstrict(iph1->remote, remote) != 0) ||
                    (cmpsaddrstrict(iph1->local, local) != 0)))
-               {
+               {     //%%%%%%%%%%%%%%%%%%%% make this a separate function - ikev2 needs it      
                        /* prevent memory leak */
                        racoon_free(iph1->remote);
                        racoon_free(iph1->local);
@@ -502,30 +455,26 @@ isakmp_main(msg, remote, local)
                        iph1->local = NULL;
 
                        /* copy-in new addresses */
-                       iph1->remote = dupsaddr((struct sockaddr *)remote);
+                       iph1->remote = dupsaddr(remote);
                        if (iph1->remote == NULL) {
                                IPSECSESSIONTRACEREVENT(iph1->parent_session,
                                                                                IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
-                                                                               CONSTSTR("failed to duplicate remote address"),
-                                                                               CONSTSTR("Failed to process phase1 message (can't duplicate remote address"));
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                  "phase1 failed: dupsaddr failed.\n");
-                               remph1(iph1);
-                               delph1(iph1);
-                               return -1;
+                                                                               CONSTSTR("Failed to duplicate remote address"),
+                                                                               CONSTSTR("Failed to process Phase 1 message (can't duplicate remote address"));
+                               plog(ASL_LEVEL_ERR,
+                                  "Phase 1 failed: dupsaddr failed.\n");
+                fatal_error(-1);
                        }
-                       iph1->local = dupsaddr((struct sockaddr *)local);
+                       iph1->local = dupsaddr(local);
                        if (iph1->local == NULL) {
                                IPSECSESSIONTRACEREVENT(iph1->parent_session,
                                                                                IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
-                                                                               CONSTSTR("failed to duplicate local address"),
-                                                                               CONSTSTR("Failed to process phase1 message (can't duplicate local address"));
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                  "phase1 failed: dupsaddr failed.\n");
-                               remph1(iph1);
-                               delph1(iph1);
-                               return -1;
-                       }
+                                                                               CONSTSTR("Failed to duplicate local address"),
+                                                                               CONSTSTR("Failed to process Phase 1 message (can't duplicate local address"));
+                               plog(ASL_LEVEL_ERR,
+                                  "Phase 1 failed: dupsaddr failed.\n");
+                fatal_error(-1);                
+            }
 
                        /* set the flag to prevent further port floating
                           (FIXME: should we allow it? E.g. when the NAT gw 
@@ -533,11 +482,11 @@ isakmp_main(msg, remote, local)
                        iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
                        
                        /* print some neat info */
-                       plog (LLV_INFO, LOCATION, NULL
+                       plog (ASL_LEVEL_INFO
                              "NAT-T: ports changed to: %s\n",
                              saddr2str_fromto("%s<->%s", (struct sockaddr *)iph1->remote, (struct sockaddr *)iph1->local));
                }
-#endif
+
                /* must be same addresses in one stream of a phase at least. */
                if (cmpsaddrstrict(iph1->remote, remote) != 0) {
                        char *saddr_db, *saddr_act;
@@ -547,8 +496,8 @@ isakmp_main(msg, remote, local)
                        STRDUP_FATAL(saddr_db);
                        STRDUP_FATAL(saddr_act);
 
-                       plog(LLV_WARNING, LOCATION, remote,
-                               "remote address mismatched. db=%s, act=%s\n",
+                       plog(ASL_LEVEL_WARNING, 
+                               "Remote address mismatched. db=%s, act=%s\n",
                                saddr_db, saddr_act);
 
                        racoon_free(saddr_db);
@@ -556,658 +505,258 @@ isakmp_main(msg, remote, local)
                }
 
                /*
-                * don't check of exchange type here because other type will be
-                * with same index, for example, informational exchange.
+                * don't check of exchange type here because other type will have
+                * the same index, for example, informational exchange.
                 */
 
-               /* XXX more acceptable check */
-
-#ifdef ENABLE_DPD
         // received ike packets: update dpd checks 
-        isakmp_reschedule_info_monitor_if_pending(iph1,
-                                                  "ike packets received from peer");
-#endif /* DPD */
-       }
-
-       switch (isakmp->etype) {
-       case ISAKMP_ETYPE_IDENT:
-       case ISAKMP_ETYPE_AGG:
-       case ISAKMP_ETYPE_BASE:
-               /* phase 1 validity check */
-               if (isakmp->msgid != 0) {
-                       plog(LLV_ERROR, LOCATION, remote,
-                               "message id should be zero in phase1.\n");
-                       return -1;
-               }
-
-               /* search for isakmp status record of phase 1 */
-               if (iph1 == NULL) {
-                       /*
-                        * the packet must be the 1st message from a initiator
-                        * or the 2nd message from the responder.
-                        */
-
-                       /* search for phase1 handle by index without r_ck */
-                       iph1 = getph1byindex0(index);
-                       if (iph1 == NULL) {
-                               /*it must be the 1st message from a initiator.*/
-                               if (memcmp(&isakmp->r_ck, r_ck0,
-                                       sizeof(cookie_t)) != 0) {
-
-                                       plog(LLV_DEBUG, LOCATION, remote,
-                                               "malformed cookie received "
-                                               "or the spi expired.\n");
-                                       return -1;
-                               }
-
-                               /* it must be responder's 1st exchange. */
-                               if (isakmp_ph1begin_r(msg, remote, local,
-                                       isakmp->etype) < 0)
-                                       return -1;
-                               break;
-
-                               /*NOTREACHED*/
-                       }
-
-                       /* it must be the 2nd message from the responder. */
-                       if (iph1->side != INITIATOR) {
-                               IPSECSESSIONTRACEREVENT(iph1->parent_session,
-                                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
-                                                                               CONSTSTR("malformed cookie and unexpected side"),
-                                                                               CONSTSTR("Failed to process phase1 message (unexpected side)"));
-                               plog(LLV_DEBUG, LOCATION, remote,
-                                       "malformed cookie received. "
-                                       "it has to be as the initiator.  %s\n",
-                                       isakmp_pindex(&iph1->index, 0));
-                               return -1;
-                       }
-               }
-
-               /*
-                * Don't delete phase 1 handler when the exchange type
-                * in handler is not equal to packet's one because of no
-                * authencication completed.
-                */
-               if (iph1->etype != isakmp->etype) {
-                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
-                                                                       IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
-                                                                       CONSTSTR("mismatched exchange type"),
-                                                                       CONSTSTR("Failed to process phase1 message (mismatched exchange type)"));
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "exchange type is mismatched: "
-                               "db=%s packet=%s, ignore it.\n",
-                               s_isakmp_etype(iph1->etype),
-                               s_isakmp_etype(isakmp->etype));
-                       return -1;
-               }
-
-#ifdef ENABLE_FRAG
-               if (isakmp->np == ISAKMP_NPTYPE_FRAG)
-                       return frag_handler(iph1, msg, remote, local);
-#endif
-
-               /* call main process of phase 1 */
-               if (ph1_main(iph1, msg) < 0) {
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "phase1 negotiation failed.\n");
-                       remph1(iph1);
-                       delph1(iph1);
-                       return -1;
-               }
-               break;
-
-       case ISAKMP_ETYPE_AUTH:
-               plog(LLV_INFO, LOCATION, remote,
-                       "unsupported exchange %d received.\n",
-                       isakmp->etype);
-               break;
-
-       case ISAKMP_ETYPE_INFO:
-       case ISAKMP_ETYPE_ACKINFO:
-               /*
-                * iph1 must be present for Information message.
-                * if iph1 is null then trying to get the phase1 status
-                * as the packet from responder againt initiator's 1st
-                * exchange in phase 1.
-                * NOTE: We think such informational exchange should be ignored.
-                */
-               if (iph1 == NULL) {
-                       iph1 = getph1byindex0(index);
-                       if (iph1 == NULL) {
-                               plog(LLV_ERROR, LOCATION, remote,
-                                       "unknown Informational "
-                                       "exchange received.\n");
-                               return -1;
-                       }
-                       if (cmpsaddrstrict(iph1->remote, remote) != 0) {
-                               plog(LLV_WARNING, LOCATION, remote,
-                                       "remote address mismatched. "
-                                       "db=%s\n",
-                                       saddr2str((struct sockaddr *)iph1->remote));
-                       }
-               }
-
-#ifdef ENABLE_FRAG
-               if (isakmp->np == ISAKMP_NPTYPE_FRAG)
-                       return frag_handler(iph1, msg, remote, local);
-#endif
-
-               if (isakmp_info_recv(iph1, msg) < 0)
-                       return -1;
-               break;
+        isakmp_reschedule_info_monitor_if_pending(iph1, "IKE packet received from peer");
 
-       case ISAKMP_ETYPE_QUICK:
-       {
-               struct ph2handle *iph2;
-
-               if (iph1 == NULL) {
-                       isakmp_info_send_nx(isakmp, remote, local,
-                               ISAKMP_NTYPE_INVALID_COOKIE, NULL);
-                       plog(LLV_ERROR, LOCATION, remote,
-                               "can't start the quick mode, "
-                               "there is no ISAKMP-SA, %s\n",
-                               isakmp_pindex((isakmp_index *)&isakmp->i_ck,
-                                       isakmp->msgid));
-                       return -1;
-               }
-#ifdef ENABLE_HYBRID
-               /* 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;
-               }
-#endif
-#ifdef ENABLE_FRAG
-               if (isakmp->np == ISAKMP_NPTYPE_FRAG)
-                       return frag_handler(iph1, msg, remote, local);
-#endif
-
-               /* check status of phase 1 whether negotiated or not. */
-               if (iph1->status != PHASE1ST_ESTABLISHED) {
-                       IPSECSESSIONTRACEREVENT(iph1->parent_session,
-                                                                       IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
-                                                                       CONSTSTR("can't start phase2 without valid phase1"),
-                                                                       CONSTSTR("Failed to start phase2 resonder (no established phase1"));
-                       plog(LLV_ERROR, LOCATION, remote,
-                               "can't start the quick mode, "
-                               "there is no valid ISAKMP-SA, %s\n",
-                               isakmp_pindex(&iph1->index, iph1->msgid));
-                       return -1;
-               }
-
-               /* search isakmp phase 2 stauts record. */
-               iph2 = getph2bymsgid(iph1, msgid);
-               if (iph2 == NULL) {
-                       /* it must be new negotiation as responder */
-                       if (isakmp_ph2begin_r(iph1, msg) < 0)
-                               return -1;
-                       return 0;
-                       /*NOTREACHED*/
-               }
-
-               /* commit bit. */
-               /* XXX
-                * we keep to set commit bit during negotiation.
-                * When SA is configured, bit will be reset.
-                * XXX
-                * don't initiate commit bit.  should be fixed in the future.
-                */
-               if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
-                       iph2->flags |= ISAKMP_FLAG_C;
-
-               if (ISSET(isakmp->flags, ISAKMP_FLAG_E) &&
-                       (iph2->ph1 == NULL || iph2->ph1->approval == NULL)) {
-                       IPSECSESSIONTRACEREVENT(iph2->parent_session,
-                                                                       IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
-                                                                       CONSTSTR("can't continue phase2 without valid phase1"),
-                                                                       CONSTSTR("Failed to continue phase2 resonder (invalid linked phase1"));
-                       plog(LLV_ERROR, LOCATION, remote,
-                                "can't start the quick mode, "
-                                "invalid linked ISAKMP-SA\n");
-                       return -1;                      
-               }
-
-               /* call main process of quick mode */
-               if (quick_main(iph2, msg) < 0) {
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                               "phase2 negotiation failed.\n");
-                       unbindph12(iph2);
-                       remph2(iph2);
-                       delph2(iph2);
-                       return -1;
-               }
        }
-               break;
-
-       case ISAKMP_ETYPE_NEWGRP:
-               if (iph1 == NULL) {
-                       plog(LLV_ERROR, LOCATION, remote,
-                               "Unknown new group mode exchange, "
-                               "there is no ISAKMP-SA.\n");
-                       return -1;
-               }
-
-#ifdef ENABLE_FRAG
-               if (isakmp->np == ISAKMP_NPTYPE_FRAG)
-                       return frag_handler(iph1, msg, remote, local);
-#endif
-
-               isakmp_newgroup_r(iph1, msg);
-               break;
-
-#ifdef ENABLE_HYBRID
-       case ISAKMP_ETYPE_CFG:
-               if (iph1 == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                            "mode config %d from %s, "
-                            "but we have no ISAKMP-SA.\n",
-                            isakmp->etype, saddr2str((struct sockaddr *)remote));
-                       return -1;
-               }
-               if (iph1->status != PHASE1ST_ESTABLISHED) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                            "mode config %d from %s, "
-                            "but ISAKMP-SA %s isn't established.\n",
-                            isakmp->etype, saddr2str((struct sockaddr *)remote),
-                                isakmp_pindex(&iph1->index, iph1->msgid));
-                       return -1;
-               }
-#ifdef ENABLE_FRAG
-               if (isakmp->np == ISAKMP_NPTYPE_FRAG)
-                       return frag_handler(iph1, msg, remote, local);
-#endif
-
-               isakmp_cfg_r(iph1, msg);
-               break;
-#endif  
-
-       case ISAKMP_ETYPE_NONE:
-       default:
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "Invalid exchange type %d from %s.\n",
-                       isakmp->etype, saddr2str((struct sockaddr *)remote));
-               return -1;
-       }
-
-       return 0;
-}
-
-/*
- * main function of phase 1.
- */
-static int
-ph1_main(iph1, msg)
-       struct ph1handle *iph1;
-       vchar_t *msg;
-{
-       int error;
-       int ini_contact = iph1->rmconf->ini_contact;
-#ifdef ENABLE_STATS
-       struct timeval start, end;
-#endif
-       int   spi_cmp;
-       u_int rekey_lifetime;
-
-       /* ignore a packet */
-       if (iph1->status == PHASE1ST_ESTABLISHED)
-               return 0;
-
-#ifdef ENABLE_STATS
-       gettimeofday(&start, NULL);
-#endif
-       /* receive */
-       if (ph1exchange[etypesw1(iph1->etype)]
-                      [iph1->side]
-                      [iph1->status] == NULL) {
-               IPSECSESSIONTRACEREVENT(iph1->parent_session,
-                                                               IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
-                                                               CONSTSTR("unavailable function"),
-                                                               CONSTSTR("Failed to process phase1 message (no state function)"));
-               plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "why isn't the function defined.\n");
-               return -1;
-       }
-       error = (ph1exchange[etypesw1(iph1->etype)]
-                           [iph1->side]
-                           [iph1->status])(iph1, msg);
-       if (error != 0) {
-
-               /* XXX
-                * When an invalid packet is received on phase1, it should
-                * be selected to process this packet.  That is to respond
-                * with a notify and delete phase 1 handler, OR not to respond
-                * and keep phase 1 handler. However, in PHASE1ST_START when
-                * acting as RESPONDER we must not keep phase 1 handler or else
-                * it will stay forever.
-                */
-
-               if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
-                            "failed to pre-process packet.\n");
-                       return -1;
-               } else {
-                       /* ignore the error and keep phase 1 handler */
-                       return 0;
-               }       
-       }
-
-#ifndef ENABLE_FRAG
-       /* free resend buffer */
-       if (iph1->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "no buffer found as sendbuf\n"); 
-               return -1;
-       }
-#endif
-
-       VPTRINIT(iph1->sendbuf);
-
-       /* turn off schedule */
-       SCHED_KILL(iph1->scr);
-
-       /* send */
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
-       if ((ph1exchange[etypesw1(iph1->etype)]
-                       [iph1->side]
-                       [iph1->status])(iph1, msg) != 0) {
-               plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "failed to process packet.\n");
-               return -1;
-       }
-
-#ifdef ENABLE_STATS
-       gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s): %8.6f",
-               "phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status),
-               timedelta(&start, &end));
-#endif
-       if (iph1->status == PHASE1ST_ESTABLISHED) {
-
-#ifdef ENABLE_STATS
-               gettimeofday(&iph1->end, NULL);
-               syslog(LOG_NOTICE, "%s(%s): %8.6f",
-                       "phase1", s_isakmp_etype(iph1->etype),
-                       timedelta(&iph1->start, &iph1->end));
-#endif
-
-#ifdef ENABLE_VPNCONTROL_PORT  
-
-               if (iph1->side == RESPONDER &&
-                       iph1->local->ss_family == AF_INET) {
-                       
-                       struct redirect *addr;
-                       
-                       LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) {
-                               if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) {
-                                       vchar_t *raddr = vmalloc(sizeof(u_int32_t));
-                               
-                                       if (raddr == NULL) {
-                                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                                       "failed to send redirect message - memory error.\n");
-                                       } else {
-                                               memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t));
-                                               (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr);
-                                               plog(LLV_DEBUG, LOCATION, iph1->remote, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address));
-                                               vfree(raddr);
-                                               if (addr->force) {
-                                                       (void)ike_session_update_ph1_ph2tree(iph1);
-                                                       isakmp_ph1expire(iph1);
-                                               }
-                                       }
-                               }
-                               return 0;
-                       }
-               }
-#endif 
-               /* save created date. */
-               (void)time(&iph1->created);
-
-               /* add to the schedule to expire, and save back pointer. */
-               iph1->sce = sched_new(iph1->approval->lifetime,
-                                                         isakmp_ph1expire_stub, iph1);
-
-               if (iph1->rmconf->initiate_ph1rekey) {
-                       if (iph1->side == INITIATOR) {
-                               spi_cmp = memcmp(&iph1->index.i_ck, &iph1->index.r_ck, sizeof(iph1->index.i_ck));
-                               if (spi_cmp == 0)
-                                       spi_cmp = 1;
-                       } else {
-                               spi_cmp = memcmp(&iph1->index.r_ck, &iph1->index.i_ck, sizeof(iph1->index.r_ck));
-                               if (spi_cmp == 0)
-                                       spi_cmp = -1;
-                       }
-                       rekey_lifetime = ike_session_get_rekey_lifetime((spi_cmp > 0),
-                                                                                                                       iph1->approval->lifetime);
-                       if (rekey_lifetime) {
-                               iph1->sce_rekey = sched_new(rekey_lifetime,
-                                                                                       isakmp_ph1rekeyexpire_stub,
-                                                                                       iph1);
-                       } else {
-                               /* iph1->approval->lifetime is too small (e.g. 1) so why bother?
-                                * LOG ERROR
-                                */
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                        "failed to get rekey timer - lifetime is too small... probably.\n");
-                       }
-               }
-
-#ifdef ENABLE_HYBRID
-               /* ignore xauth if it is a rekey */
-               if (!iph1->is_rekey &&
-                       iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
-                       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:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
-                               xauth_sendreq(iph1);
-                               /* XXX Don't process INITIAL_CONTACT */
-                               ini_contact = 0;
-                               break;
-                       default:
-                               break;
-                       }
-               }
-#endif
-#ifdef ENABLE_DPD
-               /* Schedule the r_u_there.... */
-               if(iph1->dpd_support && iph1->rmconf->dpd_interval)
-                       isakmp_sched_r_u(iph1, 0);
-#endif
-
-               /* INITIAL-CONTACT processing */
-               /* ignore initial-contact if it is a rekey */
-               /* don't send anything if local test mode. */
-               if (!iph1->is_rekey && !f_local && ini_contact && !getcontacted(iph1->remote)) {
-                       /* send INITIAL-CONTACT */
-                       isakmp_info_send_n1(iph1,
-                                       ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
-                       /* insert a node into contacted list. */
-                       if (inscontacted(iph1->remote) == -1) {
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
-                                       "failed to add contacted list.\n");
-                               /* ignore */
-                       }
-               }
-
-               log_ph1established(iph1);
-               plog(LLV_DEBUG, LOCATION, NULL, "===\n");
-               
-               /* 
-                * SA up shell script hook: do it now for rekeys, otherwise only
-                * if ISAKMP mode config wasn't requested. In the later
-                * case it is done when we receive the configuration.
-                */
-               if ((iph1->status == PHASE1ST_ESTABLISHED) &&
-                   (iph1->is_rekey || !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:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
-                       /* Unimplemeted... */
-                       case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
-                       case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
-                               break;
-#endif
-                       default:
-                               script_hook(iph1, SCRIPT_PHASE1_UP);
-                               break;
-                       }
-               }
-
-               ike_session_cleanup_other_established_ph1s(iph1->parent_session, iph1);
-
-#ifdef ENABLE_VPNCONTROL_PORT
-               vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
-               vpncontrol_notify_peer_resp_ph1(1, iph1);
-#endif
-
-       }
-
-       return 0;
-}
-
-/*
- * main function of quick mode.
- */
-static int
-quick_main(iph2, msg)
-       struct ph2handle *iph2;
-       vchar_t *msg;
-{
-       struct isakmp *isakmp = (struct isakmp *)msg->v;
-       int error;
-#ifdef ENABLE_STATS
-       struct timeval start, end;
-#endif
-
-       /* ignore a packet */
-       if (iph2->status == PHASE2ST_ESTABLISHED
-        || iph2->status == PHASE2ST_GETSPISENT)
-               return 0;
-
-#ifdef ENABLE_STATS
-       gettimeofday(&start, NULL);
-#endif
-
-       /* receive */
-       if (ph2exchange[etypesw2(isakmp->etype)]
-                      [iph2->side]
-                      [iph2->status] == NULL) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-                       "why isn't the function defined.\n");
-               return -1;
-       }
-       error = (ph2exchange[etypesw2(isakmp->etype)]
-                           [iph2->side]
-                           [iph2->status])(iph2, msg);
-       if (error != 0) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-                       "failed to pre-process packet.\n");
-               if (error == ISAKMP_INTERNAL_ERROR)
-                       return 0;
-               isakmp_info_send_n1(iph2->ph1, error, NULL);
-               return -1;
-       }
-
-       /* when using commit bit, status will be reached here. */
-       //if (iph2->status == PHASE2ST_ADDSA)   //%%% BUG FIX - wrong place
-       //      return 0;
-
-       /* free resend buffer */
-       if (iph2->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "no buffer found as sendbuf\n"); 
-               return -1;
-       }
-       VPTRINIT(iph2->sendbuf);
-
-       /* turn off schedule */
-       SCHED_KILL(iph2->scr);
-               
-       /* when using commit bit, status will be reached here. */
-       if (iph2->status == PHASE2ST_ADDSA)             //%%% BUG FIX - moved to here
-               return 0;
+      
+    //
+    // Check exchange type and process accordingly
+    //
+       switch (isakmp->etype) {
 
-       /* send */
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
-       if ((ph2exchange[etypesw2(isakmp->etype)]
-                       [iph2->side]
-                       [iph2->status])(iph2, msg) != 0) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-                       "failed to process packet.\n");
-               return -1;
+        case ISAKMP_ETYPE_IDENT:
+        case ISAKMP_ETYPE_AGG:
+            {   
+                /* phase 1 validity check */
+                if (isakmp->msgid != 0) {
+                    plog(ASL_LEVEL_ERR, "Message id should be zero in Phase 1.\n");
+                    return;
+                }
+                
+                /* search for isakmp status record of phase 1 */
+                if (iph1 == NULL) {
+                    /*
+                     * the packet must be the 1st message from a initiator
+                     * or the 2nd message from the responder.
+                     */
+                    
+                    /* search for phase1 handle by index without r_ck */
+                    iph1 = ike_session_getph1byindex0(session, index);
+                    if (iph1 == NULL) {
+                        /*it must be the 1st message from a initiator.*/
+                        if (memcmp(&isakmp->r_ck, r_ck0,
+                                   sizeof(cookie_t)) != 0) {
+                            
+                            plog(ASL_LEVEL_DEBUG, "Malformed cookie received "
+                                 "or the spi expired.\n");
+                            return;
+                        }
+                        
+                        /* Initiation of new exchange */
+                        ikev1_ph1begin_r(session, msg, remote, local, isakmp->etype);
+                        return;
+                    }
+                }
+                
+                /*
+                 * Don't delete phase 1 handler for mismatch
+                 * because of no authentication has been completed.
+                 */
+                if (iph1->etype != isakmp->etype) {
+                    IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                            IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
+                                            CONSTSTR("Mismatched exchange type"),
+                                            CONSTSTR("Failed to process Phase 1 message (mismatched exchange type)"));
+                    plog(ASL_LEVEL_ERR,
+                         "Exchange type is mismatched: "
+                         "db=%s packet=%s, ignore it.\n",
+                         s_isakmp_etype(iph1->etype),
+                         s_isakmp_etype(isakmp->etype));
+                    return;
+                }
+                
+                if (isakmp->np == ISAKMP_NPTYPE_FRAG) {
+                    frag_handler(iph1, msg, remote, local);
+                    return;
+                }
+                fsm_ikev1_phase1_process_payloads(iph1, msg);
+            }
+            break;
+            
+        case ISAKMP_ETYPE_INFO:
+        case ISAKMP_ETYPE_ACKINFO:
+            {
+                /*
+                 * iph1 must be present for Information message.
+                 * if iph1 is null then trying to get the phase1 status
+                 * as the packet from responder againt initiator's 1st
+                 * exchange in phase 1.
+                 * NOTE: We think such informational exchange should be ignored.
+                 */
+                if (iph1 == NULL) {
+                    iph1 = ike_session_getph1byindex0(session, index);
+                    if (iph1 == NULL) {
+                        plog(ASL_LEVEL_ERR, "Unknown Informational exchange received.\n");
+                        return;
+                    }
+                    if (cmpsaddrstrict(iph1->remote, remote) != 0) {
+                        plog(ASL_LEVEL_WARNING,
+                             "Remote address mismatched. "
+                             "db=%s\n",
+                             saddr2str((struct sockaddr *)iph1->remote));
+                    }
+                }                
+                if (isakmp->np == ISAKMP_NPTYPE_FRAG)
+                    return frag_handler(iph1, msg, remote, local);
+                
+                if (isakmp_info_recv(iph1, msg) < 0)
+                    return;
+            }
+            break;
+            
+        case ISAKMP_ETYPE_QUICK:
+            {
+                u_int32_t msgid = isakmp->msgid;
+                phase2_handle_t *iph2;
+                
+                if (iph1 == NULL) {
+                    isakmp_info_send_nx(isakmp, remote, local,
+                                        ISAKMP_NTYPE_INVALID_COOKIE, NULL);
+                    plog(ASL_LEVEL_ERR, "Can't start the quick mode, "
+                         "there is no ISAKMP-SA, %s\n", isakmp_pindex((isakmp_index *)&isakmp->i_ck,
+                                                                      isakmp->msgid));
+                    return;
+                }
+    #ifdef ENABLE_HYBRID
+                /* 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;
+                }
+    #endif
+                if (isakmp->np == ISAKMP_NPTYPE_FRAG) {
+                    frag_handler(iph1, msg, remote, local);
+                    return;
+                }
+                
+                /* check status of phase 1 whether negotiated or not. */
+                if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
+                    IPSECSESSIONTRACEREVENT(iph1->parent_session,
+                                            IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
+                                            CONSTSTR("Can't start Phase 2 without valid Phase 1"),
+                                            CONSTSTR("Failed to start Phase 2 responder (no established Phase 1"));
+                    plog(ASL_LEVEL_ERR, "can't start the quick mode, "
+                         "there is no valid ISAKMP-SA, %s\n", isakmp_pindex(&iph1->index, iph1->msgid));
+                    return;
+                }
+                
+                /* search isakmp phase 2 stauts record. */
+                iph2 = ike_session_getph2bymsgid(iph1, msgid);
+                if (iph2 == NULL) {
+                    /* it must be new negotiation as responder */
+                    ikev1_ph2begin_r(iph1, msg);
+                    return;
+                }
+                
+                /* commit bit. */
+                /* XXX
+                 * we keep to set commit bit during negotiation.
+                 * When SA is configured, bit will be reset.
+                 * XXX
+                 * don't initiate commit bit.  should be fixed in the future.
+                 */
+                if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
+                    iph2->flags |= ISAKMP_FLAG_C;
+                
+                if (ISSET(isakmp->flags, ISAKMP_FLAG_E) &&
+                    (iph2->ph1 == NULL || iph2->ph1->approval == NULL)) {
+                    IPSECSESSIONTRACEREVENT(iph2->parent_session,
+                                            IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
+                                            CONSTSTR("Can't continue Phase 2 without valid Phase 1"),
+                                            CONSTSTR("Failed to continue Phase 2 resonder (invalid linked Phase 1"));
+                    plog(ASL_LEVEL_ERR, "can't start the quick mode, "
+                         "invalid linked ISAKMP-SA\n");
+                    return;                    
+                }
+                fsm_ikev1_phase2_process_payloads(iph2, msg);
+            }
+            break;
+            
+        case ISAKMP_ETYPE_CFG:
+            {
+                if (iph1 == NULL) {
+                    plog(ASL_LEVEL_ERR,
+                         "mode config %d from %s, "
+                         "but we have no ISAKMP-SA.\n",
+                         isakmp->etype, saddr2str((struct sockaddr *)remote));
+                    return;
+                }
+                if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
+                    plog(ASL_LEVEL_ERR,
+                         "mode config %d from %s, "
+                         "but ISAKMP-SA %s isn't established.\n",
+                         isakmp->etype, saddr2str((struct sockaddr *)remote),
+                         isakmp_pindex(&iph1->index, iph1->msgid));
+                    return;
+                }
+                if (isakmp->np == ISAKMP_NPTYPE_FRAG)
+                    return frag_handler(iph1, msg, remote, local);
+                isakmp_cfg_r(iph1, msg);
+            }
+            break;
+
+        case ISAKMP_ETYPE_NEWGRP:        
+        case ISAKMP_ETYPE_AUTH:
+        case ISAKMP_ETYPE_NONE:
+        default:
+            plog(ASL_LEVEL_ERR,
+                 "Invalid exchange type %d from %s.\n",
+                 isakmp->etype, saddr2str((struct sockaddr *)remote));
+            break;
        }
-
-#ifdef ENABLE_STATS
-       gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s): %8.6f",
-               "phase2",
-               s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
-               timedelta(&start, &end));
-#endif
-
-       return 0;
 }
 
 /* new negotiation of phase 1 for initiator */
 int
-isakmp_ph1begin_i(rmconf, remote, local, started_by_api)
-       struct remoteconf *rmconf;
-       struct sockaddr_storage *remote, *local;
-       int started_by_api;
+ikev1_ph1begin_i(ike_session_t *session, struct remoteconf *rmconf, struct sockaddr_storage *remote, 
+                 struct sockaddr_storage *local, int started_by_api)
 {
-       struct ph1handle *iph1;
+
+       phase1_handle_t *iph1;
 #ifdef ENABLE_STATS
        struct timeval start, end;
 #endif
 
+    if (session == NULL) {
+        session = ike_session_get_session(local, remote, 1);
+        if (!session) {
+            plog (ASL_LEVEL_INFO, "failed to allocate or find ike session.\n");
+            fatal_error(-1);
+        }
+    }
+        
        /* get new entry to isakmp status table. */
-       iph1 = newph1();
+       iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1);
        if (iph1 == NULL)
                return -1;
 
-       iph1->status = PHASE1ST_START;
        iph1->rmconf = rmconf;
-       if (link_rmconf_to_ph1(rmconf) < 0) {
-               plog(LLV_ERROR, LOCATION, remote,
-                        "couldn't link "
-                        "configuration.\n");
-               iph1->rmconf = NULL;
-               /* don't call remph1(iph1) until after insph1(iph1) is called */
-               delph1(iph1);
-               return -1;
-       }
+    retain_rmconf(iph1->rmconf);
        iph1->side = INITIATOR;
        iph1->started_by_api = started_by_api;
-       iph1->version = ISAKMP_VERSION_NUMBER;
+       iph1->version = ISAKMP_VERSION_NUMBER_IKEV1;
        iph1->msgid = 0;
        iph1->flags = 0;
        iph1->ph2cnt = 0;
-#ifdef HAVE_GSSAPI
-       iph1->gssapi_state = NULL;
-#endif
+
 #ifdef ENABLE_HYBRID
        if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
                /* don't call remph1(iph1) until after insph1(iph1) is called */
-               delph1(iph1);
+               ike_session_delph1(iph1);
                return -1;
        }
 #endif
-#ifdef ENABLE_FRAG
 
        if(rmconf->ike_frag == ISAKMP_FRAG_FORCE)
                iph1->frag = 1;
        else
                iph1->frag = 0;
        iph1->frag_chain = NULL;
-#endif
        iph1->approval = NULL;
 
        /* XXX copy remote address */
@@ -1217,12 +766,9 @@ isakmp_ph1begin_i(rmconf, remote, local, started_by_api)
                return -1;
        }
 
-       (void)insph1(iph1);
-
-       if (ike_session_link_ph1_to_session(iph1) != 0) {
-               plog(LLV_DEBUG, LOCATION, NULL, "Failed to link ph1 to session\n");
-               remph1(iph1);
-               delph1(iph1);
+       if (ike_session_link_phase1(session, iph1) != 0) {
+               plog(ASL_LEVEL_DEBUG, "Failed to link ph1 to session\n");
+               ike_session_delph1(iph1);
                return -1;
        }
        // HACK!!! to track rekeys across SIGHUPs
@@ -1235,20 +781,26 @@ isakmp_ph1begin_i(rmconf, remote, local, started_by_api)
 
        /* start phase 1 exchange */
        iph1->etype = rmconf->etypes->type;
-
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
+    if (iph1->etype == ISAKMP_ETYPE_IDENT)
+        fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_I_START);
+    else if (iph1->etype == ISAKMP_ETYPE_AGG)
+        fsm_set_state(&iph1->status, IKEV1_STATE_AGG_I_START);
+    else
+        return -1;
+
+       plog(ASL_LEVEL_DEBUG, "===\n");
     {
        char *a;
 
        a = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
        STRDUP_FATAL(a);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO,
                "initiate new phase 1 negotiation: %s<=>%s\n",
                a, saddr2str((struct sockaddr *)iph1->remote));
        racoon_free(a);
     }
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO,
                "begin %s mode.\n",
                s_isakmp_etype(iph1->etype));
 
@@ -1257,23 +809,17 @@ isakmp_ph1begin_i(rmconf, remote, local, started_by_api)
        gettimeofday(&start, NULL);
 #endif
 
-       IPSECLOGASLMSG("IPSec Phase1 started (Initiated by me).\n");
-
-       /* start exchange */
-       if ((ph1exchange[etypesw1(iph1->etype)]
-                       [iph1->side]
-                       [iph1->status])(iph1, NULL) != 0) {
-               /* failed to start phase 1 negotiation */
-               remph1(iph1);
-               delph1(iph1);
+       IPSECLOGASLMSG("IPSec Phase 1 started (Initiated by me).\n");
 
+    if (fsm_ikev1_phase1_send_response(iph1, NULL)) {
+        ike_session_unlink_phase1(iph1);
                return -1;
        }
 
 #ifdef ENABLE_STATS
        gettimeofday(&end, NULL);
        syslog(LOG_NOTICE, "%s(%s): %8.6f",
-               "phase1",
+               "Phase 1",
                s_isakmp_state(iph1->etype, iph1->side, iph1->status),
                timedelta(&start, &end));
 #endif
@@ -1287,14 +833,13 @@ isakmp_ph1begin_i(rmconf, remote, local, started_by_api)
 
 /* new negotiation of phase 1 for responder */
 static int
-isakmp_ph1begin_r(msg, remote, local, etype)
-       vchar_t *msg;
-       struct sockaddr_storage *remote, *local;
-       u_int8_t etype;
+ikev1_ph1begin_r(ike_session_t *session, vchar_t *msg, struct sockaddr_storage *remote, 
+                 struct sockaddr_storage *local, u_int8_t etype)
 {
-       struct isakmp *isakmp = (struct isakmp *)msg->v;
+
+    struct isakmp *isakmp = (struct isakmp *)msg->v;
        struct remoteconf *rmconf;
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        struct etypes *etypeok;
 #ifdef ENABLE_STATS
        struct timeval start, end;
@@ -1303,7 +848,7 @@ isakmp_ph1begin_r(msg, remote, local, etype)
        /* look for my configuration */
        rmconf = getrmconf(remote);
        if (rmconf == NULL) {
-               plog(LLV_ERROR, LOCATION, remote,
+               plog(ASL_LEVEL_ERR,
                        "couldn't find "
                        "configuration.\n");
                return -1;
@@ -1312,58 +857,52 @@ isakmp_ph1begin_r(msg, remote, local, etype)
        /* check to be acceptable exchange type */
        etypeok = check_etypeok(rmconf, etype);
        if (etypeok == NULL) {
-               plog(LLV_ERROR, LOCATION, remote,
+               plog(ASL_LEVEL_ERR,
                        "not acceptable %s mode\n", s_isakmp_etype(etype));
                return -1;
        }
-
+        
        /* get new entry to isakmp status table. */
-       iph1 = newph1();
+       iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1);
        if (iph1 == NULL)
                return -1;
 
        memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
-       iph1->status = PHASE1ST_START;
-       iph1->rmconf = rmconf;
-       if (link_rmconf_to_ph1(rmconf) < 0) {
-               plog(LLV_ERROR, LOCATION, remote,
-                        "couldn't link "
-                        "configuration.\n");
-               iph1->rmconf = NULL;
-               /* don't call remph1(iph1) until after insph1(iph1) is called */
-               delph1(iph1);
-               return -1;
-       }
+       iph1->rmconf = rmconf;
+       retain_rmconf(iph1->rmconf);
        iph1->flags = 0;
        iph1->side = RESPONDER;
        iph1->started_by_api = 0;
        iph1->etype = etypeok->type;
        iph1->version = isakmp->v;
        iph1->msgid = 0;
-#ifdef HAVE_GSSAPI
-       iph1->gssapi_state = NULL;
-#endif
+    
+    if (iph1->etype == ISAKMP_ETYPE_IDENT)
+        fsm_set_state(&iph1->status, IKEV1_STATE_IDENT_R_START);
+    else if (iph1->etype == ISAKMP_ETYPE_AGG)
+        fsm_set_state(&iph1->status, IKEV1_STATE_AGG_R_START);
+    else
+        return -1;
+
+
 #ifdef ENABLE_HYBRID
        if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
                /* don't call remph1(iph1) until after insph1(iph1) is called */
-               delph1(iph1);
+               ike_session_delph1(iph1);
                return -1;
        }
 #endif
-#ifdef ENABLE_FRAG
+
        iph1->frag = 0;
        iph1->frag_chain = NULL;
-#endif
        iph1->approval = NULL;
 
-#ifdef ENABLE_NATT
        /* RFC3947 says that we MUST accept new phases1 on NAT-T floated port.
         * We have to setup this flag now to correctly generate the first reply.
         * Don't know if a better check could be done for that ?
         */
        if(extract_port(local) == lcconf->port_isakmp_natt)
                iph1->natt_flags |= (NAT_PORTS_CHANGED);
-#endif
 
        /* copy remote address */
        if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
@@ -1371,27 +910,25 @@ isakmp_ph1begin_r(msg, remote, local, etype)
                iph1 = NULL; /* deleted in copy_ph1addresses */
                return -1;
        }
-       (void)insph1(iph1);
 
-       if (ike_session_link_ph1_to_session(iph1) != 0) {
-               remph1(iph1);
-               delph1(iph1);
+       if (ike_session_link_phase1(session, iph1) != 0) {
+               ike_session_delph1(iph1);
                return -1;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
+       plog(ASL_LEVEL_DEBUG, "===\n");
     {
        char *a;
 
        a = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
        STRDUP_FATAL(a);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO,
                "respond new phase 1 negotiation: %s<=>%s\n",
                a, saddr2str((struct sockaddr *)iph1->remote));
        racoon_free(a);
     }
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO,
                "begin %s mode.\n", s_isakmp_etype(etype));
 
 #ifdef ENABLE_STATS
@@ -1399,72 +936,37 @@ isakmp_ph1begin_r(msg, remote, local, etype)
        gettimeofday(&start, NULL);
 #endif
 
-       IPSECLOGASLMSG("IPSec Phase1 started (Initiated by peer).\n");
-
-#ifndef ENABLE_FRAG
-
-       /* start exchange */
-       if ((ph1exchange[etypesw1(iph1->etype)]
-                       [iph1->side]
-                       [iph1->status])(iph1, msg) < 0
-        || (ph1exchange[etypesw1(iph1->etype)]
-                       [iph1->side]
-                       [iph1->status])(iph1, msg) < 0) {
-               plog(LLV_ERROR, LOCATION, remote,
-                       "failed to process packet.\n");
-               remph1(iph1);
-               delph1(iph1);
-               return -1;
-       }
-
-#ifdef ENABLE_STATS
-       gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s): %8.6f",
-               "phase1",
-               s_isakmp_state(iph1->etype, iph1->side, iph1->status),
-               timedelta(&start, &end));
-#endif
-#ifdef ENABLE_VPNCONTROL_PORT
-       vpncontrol_notify_phase_change(1, FROM_REMOTE, iph1, NULL);
-#endif
-
-       return 0;
-
-#else /* ENABLE_FRAG */
+       IPSECLOGASLMSG("IPSec Phase 1 started (Initiated by peer).\n");
 
        /* now that we have a phase1 handle, feed back into our
         * main receive function to catch fragmented packets
         */
-
-       return isakmp_main(msg, remote, local);
-
-#endif /* ENABLE_FRAG */
-
+       isakmp_main(msg, remote, local);
+    return 0;
 }
 
 /* new negotiation of phase 2 for initiator */
 static int
-isakmp_ph2begin_i(iph1, iph2)
-       struct ph1handle *iph1;
-       struct ph2handle *iph2;
+ikev1_ph2begin_i(phase1_handle_t *iph1, phase2_handle_t *iph2)
 {
+    
 #ifdef ENABLE_HYBRID
        if (xauth_check(iph1) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                    "Attempt to start phase 2 whereas Xauth failed\n");
                return -1;
        }
 #endif
 
        /* found ISAKMP-SA. */
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
-       plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
+       plog(ASL_LEVEL_DEBUG, "===\n");
+       plog(ASL_LEVEL_DEBUG, "begin QUICK mode.\n");
     {
        char *a;
        a = racoon_strdup(saddr2str((struct sockaddr *)iph2->src));
        STRDUP_FATAL(a);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO,
                "initiate new phase 2 negotiation: %s<=>%s\n",
                a, saddr2str((struct sockaddr *)iph2->dst));
        racoon_free(a);
@@ -1473,26 +975,13 @@ isakmp_ph2begin_i(iph1, iph2)
 #ifdef ENABLE_STATS
        gettimeofday(&iph2->start, NULL);
 #endif
-       /* found isakmp-sa */
-       if (iph2->ph1 && iph1 != iph2->ph1) {
-               plog(LLV_DEBUG2, LOCATION, NULL, "phase2 already bound in %s.\n",__FUNCTION__);
-               rebindph12(iph1, iph2);
-       } else if (!iph2->ph1) {
-               bindph12(iph1, iph2);
-       }
-       iph2->is_dying = 0;
-       if (ike_session_link_ph2_to_session(iph2) != 0) {
-               return -1;
-       }
-       iph2->status = PHASE2ST_STATUS2;
 
-       IPSECLOGASLMSG("IPSec Phase2 started (Initiated by me).\n");
+       iph2->is_dying = 0;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_START);
 
-       if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
-                        [iph2->side]
-                        [iph2->status])(iph2, NULL) < 0) {
+       IPSECLOGASLMSG("IPSec Phase 2 started (Initiated by me).\n");
+    if (quick_iprep(iph2, NULL))
                return -1;
-       }
        
 #ifdef ENABLE_VPNCONTROL_PORT
        vpncontrol_notify_phase_change(1, FROM_LOCAL, NULL, iph2);
@@ -1503,45 +992,43 @@ isakmp_ph2begin_i(iph1, iph2)
 
 /* new negotiation of phase 2 for responder */
 static int
-isakmp_ph2begin_r(iph1, msg)
-       struct ph1handle *iph1;
-       vchar_t *msg;
+ikev1_ph2begin_r(phase1_handle_t *iph1, vchar_t *msg)
 {
        struct isakmp *isakmp = (struct isakmp *)msg->v;
-       struct ph2handle *iph2 = 0;
+       phase2_handle_t *iph2 = 0;
        int error;
 #ifdef ENABLE_STATS
        struct timeval start, end;
 #endif
 #ifdef ENABLE_HYBRID
        if (xauth_check(iph1) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "Attempt to start phase 2 whereas Xauth failed\n");
+               plog(ASL_LEVEL_ERR,
+                   "Attempt to start Phase 2 whereas Xauth failed\n");
                return -1;
        }
 #endif
 
-       iph2 = newph2();
+       iph2 = ike_session_newph2(ISAKMP_VERSION_NUMBER_IKEV1, PHASE2_TYPE_SA);
        if (iph2 == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "failed to allocate phase2 entry.\n");
+               plog(ASL_LEVEL_ERR,
+                       "failed to allocate Phase 2 entry.\n");
                return -1;
        }
 
-       iph2->ph1 = iph1;
        iph2->side = RESPONDER;
-       iph2->status = PHASE2ST_START;
+       iph2->version = ISAKMP_VERSION_NUMBER_IKEV1;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_START);
        iph2->flags = isakmp->flags;
        iph2->msgid = isakmp->msgid;
        iph2->seq = pk_getseq();
        iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
        if (iph2->ivm == NULL) {
-               delph2(iph2);
+               ike_session_delph2(iph2);
                return -1;
        }
-       iph2->dst = dupsaddr((struct sockaddr *)iph1->remote);  /* XXX should be considered */
+       iph2->dst = dupsaddr(iph1->remote);     /* XXX should be considered */
        if (iph2->dst == NULL) {
-               delph2(iph2);
+               ike_session_delph2(iph2);
                return -1;
        }
        switch (iph2->dst->ss_family) {
@@ -1558,15 +1045,15 @@ isakmp_ph2begin_r(iph1, msg)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "invalid family: %d\n", iph2->dst->ss_family);
-               delph2(iph2);
+               ike_session_delph2(iph2);
                return -1;
        }
 
-       iph2->src = dupsaddr((struct sockaddr *)iph1->local);   /* XXX should be considered */
+       iph2->src = dupsaddr(iph1->local);      /* XXX should be considered */
        if (iph2->src == NULL) {
-               delph2(iph2);
+               ike_session_delph2(iph2);
                return -1;
        }
        switch (iph2->src->ss_family) {
@@ -1583,31 +1070,24 @@ isakmp_ph2begin_r(iph1, msg)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "invalid family: %d\n", iph2->src->ss_family);
-               delph2(iph2);
-               return -1;
-       }
-
-       /* add new entry to isakmp status table */
-       insph2(iph2);
-       bindph12(iph1, iph2);
-       iph2->is_dying = 0;
-       if (ike_session_link_ph2_to_session(iph2) != 0) {
-               unbindph12(iph2);
-               remph2(iph2);
-               delph2(iph2);
+               ike_session_delph2(iph2);
                return -1;
        }
        
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
+       if (ike_session_link_ph2_to_ph1(iph1, iph2))
+        return -1;    
+       iph2->is_dying = 0;
+
+       plog(ASL_LEVEL_DEBUG, "===\n");
     {
        char *a;
 
        a = racoon_strdup(saddr2str((struct sockaddr *)iph2->src));
        STRDUP_FATAL(a);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO,
                "respond new phase 2 negotiation: %s<=>%s\n",
                a, saddr2str((struct sockaddr *)iph2->dst));
        racoon_free(a);
@@ -1617,52 +1097,148 @@ isakmp_ph2begin_r(iph1, msg)
        gettimeofday(&start, NULL);
 #endif
 
-       IPSECLOGASLMSG("IPSec Phase2 started (Initiated by peer).\n");
-
-       error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
-                          [iph2->side]
-                          [iph2->status])(iph2, msg);
-       if (error != 0) {
-               plog(LLV_ERROR, LOCATION, iph1->remote,
-                       "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;
-       }
+       IPSECLOGASLMSG("IPSec Phase 2 started (Initiated by peer).\n");
 
-       /* send */
-       plog(LLV_DEBUG, LOCATION, NULL, "===\n");
-       if ((ph2exchange[etypesw2(isakmp->etype)]
-                       [iph2->side]
-                       [iph2->status])(iph2, msg) < 0) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-                       "failed to process packet.\n");
-               /* don't release handler */
-               return -1;
-       }
-#ifdef ENABLE_STATS
-       gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s): %8.6f",
-               "phase2",
-               s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
-               timedelta(&start, &end));
-#endif
+    error = fsm_ikev1_phase2_process_payloads(iph2, msg);
+    if (error)
+        return error;
 
 #ifdef ENABLE_VPNCONTROL_PORT
        vpncontrol_notify_phase_change(1, FROM_REMOTE, NULL, iph2);
 #endif
 
-
        return 0;
 }
 
+int
+ikev1_phase1_established(phase1_handle_t *iph1)
+{
+    int   spi_cmp;
+    u_int rekey_lifetime;
+    int ini_contact = iph1->rmconf->ini_contact;
+    
+#ifdef ENABLE_STATS
+    gettimeofday(&iph1->end, NULL);
+    syslog(LOG_NOTICE, "%s(%s): %8.6f",
+           "Phase 1", s_isakmp_etype(iph1->etype),
+           timedelta(&iph1->start, &iph1->end));
+#endif
+    
+#ifdef ENABLE_VPNCONTROL_PORT  
+    
+    if (iph1->side == RESPONDER &&
+        iph1->local->ss_family == AF_INET) {
+        
+        struct redirect *addr;
+        
+        LIST_FOREACH(addr, &lcconf->redirect_addresses, chain) {
+            if (((struct sockaddr_in *)iph1->local)->sin_addr.s_addr == addr->cluster_address) {
+                vchar_t *raddr = vmalloc(sizeof(u_int32_t));
+                
+                if (raddr == NULL) {
+                    plog(ASL_LEVEL_ERR,
+                         "failed to send redirect message - memory error.\n");
+                } else {
+                    memcpy(raddr->v, &addr->redirect_address, sizeof(u_int32_t));
+                    (void)isakmp_info_send_n1(iph1, ISAKMP_NTYPE_LOAD_BALANCE, raddr);
+                    plog(ASL_LEVEL_DEBUG, "sent redirect notification - address = %x.\n", ntohl(addr->redirect_address));
+                    vfree(raddr);
+                    if (addr->force) {
+                        (void)ike_session_update_ph1_ph2tree(iph1);
+                        isakmp_ph1expire(iph1);
+                    }
+                }
+            }
+            return 0;
+        }
+    }
+#endif 
+    /* save created date. */
+    (void)time(&iph1->created);
+    
+    /* add to the schedule to expire, and save back pointer. */
+    iph1->sce = sched_new(iph1->approval->lifetime,
+                          isakmp_ph1expire_stub, iph1);
+    
+    if (iph1->rmconf->initiate_ph1rekey) {
+        if (iph1->side == INITIATOR) {
+            spi_cmp = memcmp(&iph1->index.i_ck, &iph1->index.r_ck, sizeof(iph1->index.i_ck));
+            if (spi_cmp == 0)
+                spi_cmp = 1;
+        } else {
+            spi_cmp = memcmp(&iph1->index.r_ck, &iph1->index.i_ck, sizeof(iph1->index.r_ck));
+            if (spi_cmp == 0)
+                spi_cmp = -1;
+        }
+        rekey_lifetime = ike_session_get_rekey_lifetime((spi_cmp > 0),
+                                                        iph1->approval->lifetime);
+        if (rekey_lifetime) {
+            iph1->sce_rekey = sched_new(rekey_lifetime,
+                                        isakmp_ph1rekeyexpire_stub,
+                                        iph1);
+        } else {
+            /* iph1->approval->lifetime is too small (e.g. 1) so why bother?
+             * LOG ERROR
+             */
+            plog(ASL_LEVEL_ERR,
+                 "failed to get rekey timer - lifetime is too small... probably.\n");
+        }
+    }
+    
+#ifdef ENABLE_HYBRID
+    /* ignore xauth if it is a rekey */
+    if (!iph1->is_rekey &&
+        iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
+        switch(AUTHMETHOD(iph1)) {
+            case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+            case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+            case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+            case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+            case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+                xauth_sendreq(iph1);
+                /* XXX Don't process INITIAL_CONTACT */
+                ini_contact = 0;
+                break;
+            default:
+                break;
+        }
+    }
+#endif
+#ifdef ENABLE_DPD
+    /* Schedule the r_u_there.... */
+    if(iph1->dpd_support && iph1->rmconf->dpd_interval)
+        isakmp_sched_r_u(iph1, 0);
+#endif
+    
+    /* INITIAL-CONTACT processing */
+    /* ignore initial-contact if it is a rekey */
+    /* don't send anything if local test mode. */
+    if (!iph1->is_rekey && !f_local && ini_contact && !ike_session_getcontacted(iph1->remote)) {
+        /* send INITIAL-CONTACT */
+        isakmp_info_send_n1(iph1,
+                            ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
+        /* insert a node into contacted list. */
+        if (ike_session_inscontacted(iph1->remote) == -1) {
+            plog(ASL_LEVEL_ERR,
+                 "failed to add contacted list.\n");
+            /* ignore */
+        }
+    }
+    
+    log_ph1established(iph1);
+    plog(ASL_LEVEL_DEBUG, "===\n");
+    
+    ike_session_cleanup_other_established_ph1s(iph1->parent_session, iph1);
+    
+#ifdef ENABLE_VPNCONTROL_PORT
+    vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
+    vpncontrol_notify_peer_resp_ph1(1, iph1);
+#endif
+    
+    return 0;
+}
+
+
 /*
  * parse ISAKMP payloads, without ISAKMP base header.
  */
@@ -1677,7 +1253,7 @@ isakmp_parsewoh(np0, gen, len)
        vchar_t *result;
        struct isakmp_parse_t *p, *ep;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
+       plog(ASL_LEVEL_DEBUG, "begin.\n");
 
        /*
         * 5 is a magic number, but any value larger than 2 should be fine
@@ -1685,7 +1261,7 @@ isakmp_parsewoh(np0, gen, len)
         */
        result = vmalloc(sizeof(struct isakmp_parse_t) * 5);
        if (result == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get buffer.\n");
                return NULL;
        }                   
@@ -1699,19 +1275,19 @@ isakmp_parsewoh(np0, gen, len)
        while (0 < tlen && np != ISAKMP_NPTYPE_NONE) {
                if (tlen <= sizeof(struct isakmp_gen)) {
                        /* don't send information, see isakmp_ident_r1() */
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "invalid length of payload\n");
                        vfree(result);
                        return NULL;
                }
 
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG, 
                        "seen nptype=%u(%s)\n", np, s_isakmp_nptype(np));
 
                p->type = np;
                p->len = ntohs(gen->len);
                if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) {
-                       plog(LLV_DEBUG, LOCATION, NULL,
+                       plog(ASL_LEVEL_DEBUG, 
                                "invalid length of payload\n");
                        vfree(result);
                        return NULL;
@@ -1724,7 +1300,7 @@ isakmp_parsewoh(np0, gen, len)
                        off = p - ALIGNED_CAST(struct isakmp_parse_t *)result->v;
                        result = vrealloc(result, result->l * 2);
                        if (result == NULL) {
-                               plog(LLV_DEBUG, LOCATION, NULL,
+                               plog(ASL_LEVEL_DEBUG, 
                                        "failed to realloc buffer.\n");
                                vfree(result);
                                return NULL;
@@ -1744,7 +1320,7 @@ isakmp_parsewoh(np0, gen, len)
        p->len = 0;
        p->ptr = NULL;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "succeed.\n");
+       plog(ASL_LEVEL_DEBUG, "succeed.\n");
 
        return result;
 }
@@ -1771,17 +1347,13 @@ isakmp_parse(buf)
 }
 
 int
-isakmp_init(int ignore_phX, int *tentative_failures)
+isakmp_init(void)
 {
-       /* initialize a isakmp status table */
-       if (!ignore_phX) {
-               initph1tree();
-               initph2tree();
-       }
-       initctdtree();
-       init_recvdpkt();
 
-       if (isakmp_open(tentative_failures) < 0)
+       ike_session_initctdtree();
+       ike_session_init_recvdpkt();
+
+       if (isakmp_open() < 0)
                goto err;
 
        return(0);
@@ -1794,8 +1366,8 @@ err:
 void
 isakmp_cleanup()
 {
-       clear_recvdpkt();
-       clear_contacted();
+       ike_session_clear_recvdpkt();
+       ike_session_clear_contacted();
 }
 
 /*
@@ -1832,9 +1404,10 @@ isakmp_pindex(index, msgid)
        return buf;
 }
 
+
 /* open ISAKMP sockets. */
 int
-isakmp_open(int *tentative_failures)
+isakmp_open(void)
 {
        const int yes = 1;
        int ifnum = 0, encap_ifnum = 0;
@@ -1842,11 +1415,9 @@ isakmp_open(int *tentative_failures)
        int pktinfo;
 #endif
        struct myaddrs *p;
-
-       if (tentative_failures) {
-               *tentative_failures = FALSE;
-       }
-
+    int tentative_failures = 0;
+    int s;
+    
        for (p = lcconf->myaddrs; p; p = p->next) {
                if (!p->addr)
                        continue;
@@ -1861,20 +1432,20 @@ isakmp_open(int *tentative_failures)
                switch (p->addr->ss_family) {
                case AF_INET:
                        if (((struct sockaddr_in *)p->addr)->sin_addr.s_addr == 0)
-                               plog(LLV_WARNING, LOCATION, NULL,
+                               plog(ASL_LEVEL_WARNING, 
                                        "listening to wildcard address,"
                                        "broadcast IKE packet may kill you\n");
                        break;
 #ifdef INET6
                case AF_INET6:
                        if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)p->addr)->sin6_addr))
-                               plog(LLV_WARNING, LOCATION, NULL,
+                               plog(ASL_LEVEL_WARNING, 
                                        "listening to wildcard address, "
                                        "broadcast IKE packet may kill you\n");
                        break;
 #endif
                default:
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "unsupported address family %d\n",
                                lcconf->default_af);
                        goto err_and_next;
@@ -1885,7 +1456,7 @@ isakmp_open(int *tentative_failures)
                    IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)
                                            p->addr)->sin6_addr))
                {
-                       plog(LLV_DEBUG, LOCATION, NULL
+                       plog(ASL_LEVEL_DEBUG
                                "Ignoring multicast address %s\n",
                                saddr2str((struct sockaddr *)p->addr));
                                racoon_free(p->addr);
@@ -1895,14 +1466,13 @@ isakmp_open(int *tentative_failures)
 #endif
 
                if ((p->sock = socket(p->addr->ss_family, SOCK_DGRAM, 0)) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "socket (%s)\n", strerror(errno));
                        goto err_and_next;
                }
 
                if (fcntl(p->sock, F_SETFL, O_NONBLOCK) == -1)
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to put socket in non-blocking mode\n");
+                       plog(ASL_LEVEL_ERR, "failed to put socket in non-blocking mode\n");
 
                /* receive my interface address on inbound packets. */
                switch (p->addr->ss_family) {
@@ -1910,7 +1480,7 @@ isakmp_open(int *tentative_failures)
                        if (setsockopt(p->sock, IPPROTO_IP,
                                       IP_RECVDSTADDR,
                                        (const void *)&yes, sizeof(yes)) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                        "setsockopt IP_RECVDSTADDR (%s)\n", 
                                        strerror(errno));
                                goto err_and_next;
@@ -1926,7 +1496,7 @@ isakmp_open(int *tentative_failures)
                        if (setsockopt(p->sock, IPPROTO_IPV6, pktinfo,
                                        (const void *)&yes, sizeof(yes)) < 0)
                        {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                        "setsockopt IPV6_RECVDSTADDR (%d):%s\n",
                                        pktinfo, strerror(errno));
                                goto err_and_next;
@@ -1939,7 +1509,7 @@ isakmp_open(int *tentative_failures)
                if (p->addr->ss_family == AF_INET6 &&
                    setsockopt(p->sock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
                    (void *)&yes, sizeof(yes)) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                            "setsockopt IPV6_USE_MIN_MTU (%s)\n", 
                            strerror(errno));
                        return -1;
@@ -1952,7 +1522,7 @@ isakmp_open(int *tentative_failures)
                if (extract_port(p->addr) == PORT_ISAKMP) {
                        if (setsockopt(p->sock, SOL_SOCKET, SO_NOTIFYCONFLICT, 
                                (void *)&yes, sizeof(yes)) < 0) {
-                               plog(LLV_ERROR, LOCATION, p->addr,
+                               plog(ASL_LEVEL_ERR,
                                        "setsockopt (%s)\n", strerror(errno));
                                goto err_and_next;
                        }
@@ -1960,7 +1530,7 @@ isakmp_open(int *tentative_failures)
 
                if (bind(p->sock, (struct sockaddr *)p->addr, sysdep_sa_len((struct sockaddr *)p->addr)) < 0) {
                        int tmp_errno = errno;
-                       plog(LLV_ERROR, LOCATION, p->addr,
+                       plog(ASL_LEVEL_ERR,
                                "failed to bind to address %s (%s).\n",
                                saddr2str((struct sockaddr *)p->addr), strerror(tmp_errno));
 #ifdef INET6
@@ -1978,22 +1548,20 @@ isakmp_open(int *tentative_failures)
                                         */
                                        if ((ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED | IN6_IFF_DEPRECATED)) == 0) {
                                                // address may have been tentantive... invalidate sock but leave address around for another try later
-                                               plog(LLV_ERROR, LOCATION, p->addr,
+                                               plog(ASL_LEVEL_ERR,
                                                         "failed to bind to address %s: because interface address is/was not ready (flags %x).\n",
                                                         saddr2str((struct sockaddr *)p->addr), ifr6.ifr_ifru.ifru_flags6);
                                                close(p->sock);
                                                p->sock = -1;
-                                               if (tentative_failures) {
-                                                       *tentative_failures = TRUE;
-                                               }
+                                               tentative_failures = 1;
                                                continue;
                                        } else {
-                                               plog(LLV_ERROR, LOCATION, p->addr,
+                                               plog(ASL_LEVEL_ERR,
                                                         "failed to bind to address %s: because of interface address error, flags %x.\n",
                                                         saddr2str((struct sockaddr *)p->addr), ifr6.ifr_ifru.ifru_flags6);
                                        }
                                } else {
-                                       plog(LLV_ERROR, LOCATION, p->addr,
+                                       plog(ASL_LEVEL_ERR,
                                                 "failed to bind to address %s: can't read interface address flags.\n",
                                                 saddr2str((struct sockaddr *)p->addr));
                                }
@@ -2007,8 +1575,30 @@ isakmp_open(int *tentative_failures)
                ifnum++;
                if (p->udp_encap)
                        encap_ifnum++;
-
-               plog(LLV_INFO, LOCATION, NULL,
+        
+        s = p->sock;
+        
+        if (p->source != NULL) {
+            dispatch_source_cancel(p->source);
+            p->source = NULL;
+        }
+        p->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, p->sock, 0, dispatch_get_main_queue());
+        if (p->source == NULL) {
+            plog(ASL_LEVEL_ERR, "could not create isakmp socket source.");
+            return -1;
+        }
+        dispatch_source_set_event_handler(p->source, 
+                                          ^{
+                                              isakmp_handler(s);
+                                          });
+        dispatch_source_t the_source = p->source;
+        dispatch_source_set_cancel_handler(p->source,
+                                           ^{
+                                               close(s);
+                                               dispatch_release(the_source);
+                                           });        dispatch_resume(p->source);
+
+               plog(ASL_LEVEL_INFO, 
                        "%s used as isakmp port (fd=%d)\n",
                        saddr2str((struct sockaddr *)p->addr), p->sock);
                continue;
@@ -2016,29 +1606,47 @@ isakmp_open(int *tentative_failures)
        err_and_next:
                racoon_free(p->addr);
                p->addr = NULL;
-               if (! lcconf->autograbaddr && lcconf->strict_address)
+        p->sock = -1;
+               if (! lcconf->autograbaddr && lcconf->strict_address) {
                        return -1;
+        }
+        
                continue;
        }
 
        if (!ifnum) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "no address could be bound.\n");
+
                return -1;
        }
 
 #ifdef ENABLE_NATT
        if (natt_enabled_in_rmconf() && !encap_ifnum) {
-               plog(LLV_WARNING, LOCATION, NULL
+               plog(ASL_LEVEL_WARNING
                        "NAT-T is enabled in at least one remote{} section,\n");
-               plog(LLV_WARNING, LOCATION, NULL
+               plog(ASL_LEVEL_WARNING
                        "but no 'isakmp_natt' address was specified!\n");
        }
 #endif
 
+    if (tentative_failures)
+        sched_new(5, update_myaddrs, NULL);
+
        return 0;
 }
 
+void
+isakmp_suspend_sockets()
+{
+       struct myaddrs *p;
+    
+       for (p = lcconf->myaddrs; p; p = p->next) {
+        if (p->source)
+            dispatch_suspend(p->source);
+       }
+}
+
 void
 isakmp_close()
 {
@@ -2056,12 +1664,13 @@ isakmp_close_sockets()
                if (!p->addr)
                        continue;
 
-               if (p->sock >= 0) {
-                       close(p->sock);
-                       p->sock = -1;
-               }               
+        if (p->source) {
+            dispatch_source_cancel(p->source);
+            p->source = NULL;
+            p->in_use = 0;
+            p->sock = -1;
+        }
        }
-
 }
 
 
@@ -2075,25 +1684,25 @@ isakmp_close_unused()
        for (p = lcconf->myaddrs; p; p = next) {
                next = p->next;
                if (p->in_use == 0) {   // not in use ?
-       
-                       if (p->sock >= 0)
-                               close(p->sock);
-                       *prev = p->next;
+            if (p->source) {    
+                dispatch_source_cancel(p->source);
+                p->source = NULL;
+            }
+            *prev = p->next;
                        delmyaddr(p);
                } else
-                       prev = &(p->next);
+            prev = &(p->next);
        }
 }
 
 int
 isakmp_send(iph1, sbuf)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        vchar_t *sbuf;
 {
        int len = 0;
        int s;
        vchar_t *vbuf = NULL;
-
 #ifdef ENABLE_NATT
        size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0;
 
@@ -2107,14 +1716,14 @@ isakmp_send(iph1, sbuf)
                extralen = 0;
 #endif
        if (extralen)
-               plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
+               plog (ASL_LEVEL_DEBUG, "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 
           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(ASL_LEVEL_ERR
                            "vbuf allocation failed\n");
                        return -1;
                }
@@ -2132,13 +1741,13 @@ isakmp_send(iph1, sbuf)
                return -1;
        }
 
-       plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l, 
+       plog (ASL_LEVEL_DEBUG, "%zu bytes %s\n", sbuf->l, 
              saddr2str_fromto("from %s to %s", (struct sockaddr *)iph1->local, (struct sockaddr *)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(ASL_LEVEL_ERR
                            "isakmp_sendfrags failed\n");
                        if ( vbuf != NULL )
                                vfree(vbuf);
@@ -2150,7 +1759,7 @@ isakmp_send(iph1, sbuf)
                len = sendfromto(s, sbuf->v, sbuf->l,
                    iph1->local, iph1->remote, lcconf->count_persend);
                if (len == -1) {
-                       plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
+                       plog(ASL_LEVEL_ERR, "sendfromto failed\n");
                        if ( vbuf != NULL )
                                vfree(vbuf);
                        return -1;
@@ -2168,28 +1777,27 @@ void
 isakmp_ph1resend_stub(p)
        void *p;
 {
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 
-       iph1=(struct ph1handle *)p;
+       iph1=(phase1_handle_t *)p;
        if(isakmp_ph1resend(iph1) < 0){
-               if(iph1->scr != NULL){
+               if(iph1->scr != 0){
                        /* Should not happen...
                         */
-                       sched_kill(iph1->scr);
-                       iph1->scr=NULL;
+                       SCHED_KILL(iph1->scr);
                }
 
-               remph1(iph1);
-               delph1(iph1);
+               ike_session_unlink_phase1(iph1);
        }
 }
 
 int
 isakmp_ph1resend(iph1)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 {
        time_t retry_interval;
        
+    
        // make sure there is a buffer to send
        // isakmp_plist_set_all() could have returned NULL
        if (iph1->sendbuf == NULL)
@@ -2200,14 +1808,12 @@ isakmp_ph1resend(iph1)
        if (iph1->retry_counter <= 0) {
                IPSECSESSIONTRACEREVENT(iph1->parent_session,
                                                                IPSECSESSIONEVENTCODE_IKEV1_PH1_MAX_RETRANSMIT,
-                                                               CONSTSTR("Phase1 Maximum Retransmits"),
-                                                               CONSTSTR("Phase1 negotiation failed (Maximum retransmits)"));
+                                                               CONSTSTR("Phase 1 Maximum Retransmits"),
+                                                               CONSTSTR("Phase 1 negotiation failed (Maximum retransmits)"));
 
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "phase1 negotiation failed due to time up. %s\n",
+               plog(ASL_LEVEL_ERR, 
+                       "Phase 1 negotiation failed due to time up. %s\n",
                        isakmp_pindex(&iph1->index, iph1->msgid));
-               EVT_PUSH(iph1->local, iph1->remote, 
-                   EVTT_PEER_NO_RESPONSE, NULL);
                if (iph1->side == INITIATOR && iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client) {
                        /* to get around a bug on the peer, in which rekeys to port 4500 are dropped */
                        if (isakmp_ph1rekeyretry(iph1) == 0)
@@ -2222,30 +1828,28 @@ isakmp_ph1resend(iph1)
                if (iph1->rmconf->retry_counter != iph1->retry_counter) {
                        IPSECSESSIONTRACEREVENT(iph1->parent_session,
                                                                        IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
-                                                                       CONSTSTR("Phase1 Retransmit"),
+                                                                       CONSTSTR("Phase 1 Retransmit"),
                                                                        CONSTSTR("Failed to retrasmit Phase1"));
                }
-               plog(LLV_ERROR, LOCATION, iph1->remote,
-                        "phase1 negotiation failed due to send error. %s\n",
+               plog(ASL_LEVEL_ERR,
+                        "Phase 1 negotiation failed due to send error. %s\n",
                         isakmp_pindex(&iph1->index, iph1->msgid));
-               EVT_PUSH(iph1->local, iph1->remote, 
-                                EVTT_PEER_NO_RESPONSE, NULL);
                return -1;
        }
 
        if (iph1->rmconf->retry_counter != iph1->retry_counter) {
                IPSECSESSIONTRACEREVENT(iph1->parent_session,
                                                                IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
-                                                               CONSTSTR("Phase1 Retransmit"),
+                                                               CONSTSTR("Phase 1 Retransmit"),
                                                                CONSTSTR(NULL));
        }
 
-       plog(LLV_DEBUG, LOCATION, iph1->remote,
-               "resend phase1 packet %s\n",
+       plog(ASL_LEVEL_DEBUG,
+               "Resend Phase 1 packet %s\n",
                isakmp_pindex(&iph1->index, iph1->msgid));
 
        iph1->retry_counter--;
-       retry_interval = get_exp_retx_interval((iph1->rmconf->retry_counter - iph1->retry_counter),
+       retry_interval = ike_session_get_exp_retx_interval((iph1->rmconf->retry_counter - iph1->retry_counter),
                                                                                   iph1->rmconf->retry_interval);
        iph1->scr = sched_new(retry_interval,
                isakmp_ph1resend_stub, iph1);
@@ -2258,20 +1862,18 @@ void
 isakmp_ph2resend_stub(p)
        void *p;
 {
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 
-       iph2=(struct ph2handle *)p;
+       iph2=(phase2_handle_t *)p;
 
        if(isakmp_ph2resend(iph2) < 0){
-               unbindph12(iph2);
-               remph2(iph2);
-               delph2(iph2);
+               ike_session_unlink_phase2(iph2);
        }
 }
 
 int
 isakmp_ph2resend(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        time_t retry_interval;
 
@@ -2279,18 +1881,19 @@ isakmp_ph2resend(iph2)
         */
        //%%% BUG FIX - related to commit bit usage - crash happened here
        if (iph2->ph1 == 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "internal error - attempt to re-send phase2 with no phase1 bound.\n");
+               plog(ASL_LEVEL_ERR, 
+                       "Internal error - attempt to re-send Phase 2 with no Phase 1 bound.\n");
                return -1;
        }
 
-       if (iph2->ph1->status == PHASE1ST_EXPIRED){
+    
+       if (FSM_STATE_IS_EXPIRED(iph2->ph1->status)){
                IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
                                                                IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT,
-                                                               CONSTSTR("Underlying Phase1 expired"),
-                                                               CONSTSTR("Failed to retransmit phase2 (underlying phase1 expired)"));
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-                       "phase2 negotiation failed due to phase1 expired. %s\n",
+                                                               CONSTSTR("Underlying Phase 1 expired"),
+                                                               CONSTSTR("Failed to retransmit Phase 2 (underlying Phase 1 expired)"));
+               plog(ASL_LEVEL_ERR,
+                       "Phase 2 negotiation failed due to Phase 1 expired. %s\n",
                                isakmp_pindex(&iph2->ph1->index, iph2->msgid));
                return -1;
        }
@@ -2298,12 +1901,11 @@ isakmp_ph2resend(iph2)
        if (iph2->retry_counter <= 0) {
                IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
                                                                IPSECSESSIONEVENTCODE_IKEV1_PH2_MAX_RETRANSMIT,
-                                                               CONSTSTR("Phase2 maximum retransmits"),
-                                                               CONSTSTR("Phase2 negotiation failed (maximum retransmits)"));
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
-                       "phase2 negotiation failed due to time up. %s\n",
+                                                               CONSTSTR("Phase 2 maximum retransmits"),
+                                                               CONSTSTR("Phase 2 negotiation failed (maximum retransmits)"));
+               plog(ASL_LEVEL_ERR,
+                       "Phase 2 negotiation failed due to time up. %s\n",
                                isakmp_pindex(&iph2->ph1->index, iph2->msgid));
-               EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
                return -1;
        } else {
                ike_session_ph2_retransmits(iph2);
@@ -2313,29 +1915,28 @@ isakmp_ph2resend(iph2)
                if (iph2->ph1->rmconf->retry_counter != iph2->retry_counter) {
                        IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
                                                                        IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
-                                                                       CONSTSTR("Phase2 Retransmit"),
+                                                                       CONSTSTR("Phase 2 Retransmit"),
                                                                        CONSTSTR("Failed to retransmit Phase2 message"));
                }
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "phase2 negotiation failed due to send error. %s\n",
+               plog(ASL_LEVEL_ERR, 
+                       "Phase 2 negotiation failed due to send error. %s\n",
                                isakmp_pindex(&iph2->ph1->index, iph2->msgid));
-               EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
 
                return -1;
        }
        if (iph2->ph1->rmconf->retry_counter != iph2->retry_counter) {
                IPSECSESSIONTRACEREVENT(iph2->ph1->parent_session,
                                                                IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
-                                                               CONSTSTR("Phase2 Retransmit"),
+                                                               CONSTSTR("Phase 2 Retransmit"),
                                                                CONSTSTR(NULL));
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL,
-               "resend phase2 packet %s\n",
+       plog(ASL_LEVEL_DEBUG, 
+               "Resend Phase 2 packet %s\n",
                isakmp_pindex(&iph2->ph1->index, iph2->msgid));
 
        iph2->retry_counter--;
-       retry_interval = get_exp_retx_interval((iph2->ph1->rmconf->retry_counter - iph2->ph1->retry_counter),
+       retry_interval = ike_session_get_exp_retx_interval((iph2->ph1->rmconf->retry_counter - iph2->ph1->retry_counter),
                                                                                   iph2->ph1->rmconf->retry_interval);
        iph2->scr = sched_new(retry_interval,
                isakmp_ph2resend_stub, iph2);
@@ -2343,56 +1944,59 @@ isakmp_ph2resend(iph2)
 #ifdef ENABLE_DPD
     if (iph2->scr) {
         isakmp_reschedule_info_monitor_if_pending(iph2->ph1,
-                                                  "phase2 packets sent to peer: retransmit timer armed");
+                                                  "Phase 2 packets sent to peer: retransmit timer armed");
     }
 #endif /* DPD */
     
        return 0;
 }
 
+
 /* called from scheduler */
 void
 isakmp_ph1expire_stub(p)
        void *p;
 {
 
-       isakmp_ph1expire((struct ph1handle *)p);
+       isakmp_ph1expire((phase1_handle_t *)p);
 }
 
 void
 isakmp_ph1expire(iph1)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 {
        char *src, *dst;
+       phase1_handle_t *new_iph1;
 
        SCHED_KILL(iph1->sce);
 #ifdef ENABLE_DPD
     SCHED_KILL(iph1->dpd_r_u);
 #endif
 
-       if(iph1->status != PHASE1ST_EXPIRED){
+       if(!FSM_STATE_IS_EXPIRED(iph1->status)){
                src = racoon_strdup(saddr2str((struct sockaddr *)iph1->local));
                dst = racoon_strdup(saddr2str((struct sockaddr *)iph1->remote));
                STRDUP_FATAL(src);
                STRDUP_FATAL(dst);
 
-               plog(LLV_INFO, LOCATION, NULL,
+               plog(ASL_LEVEL_INFO, 
                         "ISAKMP-SA expired %s-%s spi:%s\n",
                         src, dst,
                         isakmp_pindex(&iph1->index, 0));
                racoon_free(src);
                racoon_free(dst);
-               iph1->status = PHASE1ST_EXPIRED;
-               (void)ike_session_update_ph1_ph2tree(iph1);
+               fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
+               new_iph1 = ike_session_update_ph1_ph2tree(iph1);
        }
 
        /*
         * the phase1 deletion is postponed until there is no phase2.
         */
-       if (LIST_FIRST(&iph1->ph2tree) != NULL) {
+       if (LIST_FIRST(&iph1->bound_ph2tree) != NULL) {
                iph1->sce = sched_new(1, isakmp_ph1expire_stub, iph1);
                return;
        }
+    
 
        iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
 }
@@ -2403,12 +2007,12 @@ isakmp_ph1rekeyexpire_stub(p)
 void *p;
 {
        
-       isakmp_ph1rekeyexpire((struct ph1handle *)p, FALSE);
+       isakmp_ph1rekeyexpire((phase1_handle_t *)p, FALSE);
 }
 
 void
 isakmp_ph1rekeyexpire(iph1, ignore_sess_drop_policy)
-struct ph1handle *iph1;
+phase1_handle_t *iph1;
 int               ignore_sess_drop_policy;
 {
        char              *src, *dst;
@@ -2416,9 +2020,16 @@ int               ignore_sess_drop_policy;
 
        SCHED_KILL(iph1->sce_rekey);
 
+       // We are going to start the rekey.  Let's fire off the
+       // phase1 expiration timer if it is not done yet.
+       if (!iph1->sce && iph1->approval->lifetimegap) {
+               iph1->sce = sched_new(iph1->approval->lifetimegap,
+                              isakmp_ph1expire_stub, iph1);
+       }
+    
        // early exit if iph2->sce == NULL, iph2 isn't established or if entire session is going down
-       if (iph1->sce == NULL ||
-               iph1->status != PHASE1ST_ESTABLISHED ||
+       if (iph1->sce == 0 ||
+               !FSM_STATE_IS_ESTABLISHED(iph1->status) ||
                iph1->is_dying) {
                return;
        }
@@ -2428,49 +2039,54 @@ int               ignore_sess_drop_policy;
        STRDUP_FATAL(src);
        STRDUP_FATAL(dst);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO, 
                 "ISAKMP-SA rekey-timer expired %s-%s spi:%s\n",
                 src, dst,
                 isakmp_pindex(&iph1->index, 0));
        racoon_free(src);
        racoon_free(dst);
 
-       if (!ignore_sess_drop_policy && ike_session_drop_rekey(iph1->parent_session, IKE_SESSION_REKEY_TYPE_PH1)) {
-               return;
+    {
+        if (!ignore_sess_drop_policy && ike_session_drop_rekey(iph1->parent_session, IKE_SESSION_REKEY_TYPE_PH1)) {
+            return;
+        }
        }
 
        // exit if there is another ph1 that is established (with a pending rekey timer)
        if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
-               plog(LLV_INFO, LOCATION, iph1->remote,
-                        "request for ISAKMP-SA rekey was ignored "
+               plog(ASL_LEVEL_INFO,
+                        "Request for ISAKMP-SA rekey was ignored "
                         "due to another established ph1.\n");
                return;
        }
 
        // if there is another ph1 that is negotiating, postpone this rekey for a few seconds later
        if (ike_session_has_other_negoing_ph1(iph1->parent_session, iph1)) {
-               plog(LLV_DEBUG, LOCATION, NULL, "reschedule Phase1 rekey.\n");
+               plog(ASL_LEVEL_DEBUG, "Reschedule Phase 1 rekey.\n");
                iph1->sce_rekey = sched_new(1,
                                                                        isakmp_ph1rekeyexpire_stub,
                                                                        iph1);
                return;
        }
 
-       // get rmconf to initiate rekey with
-       rmconf = iph1->rmconf;
-       if (!rmconf || rmconf->to_delete || rmconf->to_remove) {
-               rmconf = getrmconf(iph1->remote);
-       }
-       if (rmconf) {
-               /* begin quick mode */
-               plog(LLV_DEBUG, LOCATION, NULL, "begin Phase1 rekey.\n");
+    // get rmconf to initiate rekey with
+    rmconf = iph1->rmconf;
+    if (!rmconf)
+        rmconf = getrmconf(iph1->remote);
+
+    if (rmconf) {
+        /* begin quick mode */
+        plog(ASL_LEVEL_DEBUG, "Begin Phase 1 rekey.\n");
 
                /* start phase 1 negotiation as a initiator. */
-               if (isakmp_ph1begin_i(rmconf, iph1->remote, iph1->local, 0) < 0) {
-                       plog(LLV_DEBUG, LOCATION, NULL, "Phase1 rekey Failed.\n");
+        {
+                       if (ikev1_ph1begin_i(iph1->parent_session, rmconf, iph1->remote, iph1->local, 0) < 0) {
+                               plog(ASL_LEVEL_DEBUG, "Phase 1 rekey Failed.\n");
+                       }
+            iph1->is_rekey = TRUE;
                }
        } else {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "Phase1 rekey failed: no configuration found for %s.\n",
                         saddrwop2str((struct sockaddr *)iph1->remote));
        }
@@ -2478,17 +2094,19 @@ int               ignore_sess_drop_policy;
 
 int
 isakmp_ph1rekeyretry(iph1)
-struct ph1handle *iph1;
+phase1_handle_t *iph1;
 {
        char              *src, *dst;
        struct remoteconf *rmconf;
 
        // this code path is meant for floated ph1 rekeys that are failing on the first message
-       if (iph1->sce != NULL ||
-               iph1->sce_rekey != NULL ||
-               (iph1->status != PHASE1ST_MSG1SENT || ((iph1->natt_flags & NAT_PORTS_CHANGED) == 0)) ||
-               (extract_port(iph1->local) != PORT_ISAKMP_NATT && extract_port(iph1->remote) != PORT_ISAKMP_NATT) ||
-               iph1->is_dying) {
+       if (iph1->sce != 0 ||
+               iph1->sce_rekey != 0 ||
+               ((iph1->status != IKEV1_STATE_IDENT_I_MSG1SENT  && 
+          iph1->status != IKEV1_STATE_AGG_I_MSG1SENT)
+            || ((iph1->natt_flags & NAT_PORTS_CHANGED) == 0)) 
+            || (extract_port(iph1->local) != PORT_ISAKMP_NATT && extract_port(iph1->remote) != PORT_ISAKMP_NATT) 
+            || iph1->is_dying) {
                return -1;
        }
 
@@ -2497,7 +2115,7 @@ struct ph1handle *iph1;
        STRDUP_FATAL(src);
        STRDUP_FATAL(dst);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO, 
                 "ISAKMP-SA rekey failed... retrying %s-%s spi:%s\n",
                 src, dst,
                 isakmp_pindex(&iph1->index, 0));
@@ -2505,7 +2123,7 @@ struct ph1handle *iph1;
        racoon_free(dst);
 
        if (ike_session_drop_rekey(iph1->parent_session, IKE_SESSION_REKEY_TYPE_PH1)) {
-               plog(LLV_INFO, LOCATION, iph1->remote,
+               plog(ASL_LEVEL_INFO,
                         "request for ISAKMP-SA rekey was ignored "
                         "due to idleness.\n");
                return 0;
@@ -2513,7 +2131,7 @@ struct ph1handle *iph1;
 
        // exit if there is another ph1 that is established (with a pending rekey timer)
        if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
-               plog(LLV_INFO, LOCATION, iph1->remote,
+               plog(ASL_LEVEL_INFO,
                         "request to retry ISAKMP-SA rekey was ignored "
                         "due to another established ph1.\n");
                return -1;
@@ -2530,16 +2148,17 @@ struct ph1handle *iph1;
        rmconf = getrmconf(iph1->remote);
        if (rmconf) {
                /* begin quick mode */
-               plog(LLV_DEBUG, LOCATION, NULL, "begin Phase1 rekey retry.\n");
+               plog(ASL_LEVEL_DEBUG, "begin Phase 1 rekey retry.\n");
 
                /* start phase 1 negotiation as a initiator. */
-               if (isakmp_ph1begin_i(rmconf, iph1->remote, iph1->local, 0) < 0) {
-                       plog(LLV_DEBUG, LOCATION, NULL, "Phase1 rekey retry Failed.\n");
+               if (ikev1_ph1begin_i(iph1->parent_session, rmconf, iph1->remote, iph1->local, 0) < 0) {
+                       plog(ASL_LEVEL_DEBUG, "Phase 1 rekey retry Failed.\n");
                        return -1;
                }
+               iph1->is_rekey = TRUE;
        } else {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "Phase1 rekey retry failed: no configuration found for %s.\n",
+               plog(ASL_LEVEL_ERR,
+                        "Phase 1 rekey retry failed: no configuration found for %s.\n",
                         saddrwop2str((struct sockaddr *)iph1->remote));
                return -1;
        }
@@ -2552,12 +2171,12 @@ isakmp_ph1delete_stub(p)
        void *p;
 {
 
-       isakmp_ph1delete((struct ph1handle *)p);
+       isakmp_ph1delete((phase1_handle_t *)p);
 }
 
 void
 isakmp_ph1delete(iph1)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 {
        char *src, *dst;
 
@@ -2567,11 +2186,11 @@ isakmp_ph1delete(iph1)
     SCHED_KILL(iph1->dpd_r_u);
 #endif    
 
-       if (LIST_FIRST(&iph1->ph2tree) != NULL) {
+       if (LIST_FIRST(&iph1->bound_ph2tree) != NULL) {
                iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
                return;
        }
-
+    
     isakmp_info_send_d1(iph1);
 
        /* don't re-negosiation when the phase 1 SA expires. */
@@ -2581,15 +2200,13 @@ isakmp_ph1delete(iph1)
        STRDUP_FATAL(src);
        STRDUP_FATAL(dst);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO, 
                "ISAKMP-SA deleted %s-%s spi:%s\n",
                src, dst, isakmp_pindex(&iph1->index, 0));
-       EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
        racoon_free(src);
        racoon_free(dst);
-
-       remph1(iph1);
-       delph1(iph1);
+    
+       ike_session_unlink_phase1(iph1);
 
        return;
 }
@@ -2605,16 +2222,16 @@ isakmp_ph2expire_stub(p)
        void *p;
 {
 
-       isakmp_ph2expire((struct ph2handle *)p);
+       isakmp_ph2expire((phase2_handle_t *)p);
 }
 
 void
 isakmp_ph2expire(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        char *src, *dst;
 
-       if (iph2->status == PHASE2ST_EXPIRED) {
+       if (FSM_STATE_IS_EXPIRED(iph2->status)) {
                return;
        }
 
@@ -2625,27 +2242,25 @@ isakmp_ph2expire(iph2)
        STRDUP_FATAL(src);
        STRDUP_FATAL(dst);
 
-       plog(LLV_INFO, LOCATION, NULL,
-               "phase2 sa expired %s-%s\n", src, dst);
+       plog(ASL_LEVEL_INFO, 
+               "Phase 2 sa expired %s-%s\n", src, dst);
        racoon_free(src);
        racoon_free(dst);
 
        // delete outgoing SAs
-       if (iph2->status == PHASE2ST_ESTABLISHED && iph2->approval) {
+       if (FSM_STATE_IS_ESTABLISHED(iph2->status) && iph2->approval) {
                struct saproto *pr;
 
                for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
                        if (pr->ok) {
                                pfkey_send_delete(lcconf->sock_pfkey,
-                                  ipsecdoi2pfkey_proto(pr->proto_id),
-                                  IPSEC_MODE_ANY,
-                                  iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */);
-                       }
+                                                                 ipsecdoi2pfkey_proto(pr->proto_id),
+                                                                 IPSEC_MODE_ANY,
+                                                                 iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */);
                }
        }
-
-       iph2->status = PHASE2ST_EXPIRED;
-
+    if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1)
+        fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
        iph2->sce = sched_new(1, isakmp_ph2delete_stub, iph2);
 
        return;
@@ -2657,12 +2272,12 @@ isakmp_ph2delete_stub(p)
        void *p;
 {
 
-       isakmp_ph2delete((struct ph2handle *)p);
+       isakmp_ph2delete((phase2_handle_t *)p);
 }
 
 void
 isakmp_ph2delete(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        char *src, *dst;
 
@@ -2673,14 +2288,12 @@ isakmp_ph2delete(iph2)
        STRDUP_FATAL(src);
        STRDUP_FATAL(dst);
 
-       plog(LLV_INFO, LOCATION, NULL,
-               "phase2 sa deleted %s-%s\n", src, dst);
+       plog(ASL_LEVEL_INFO, 
+               "Phase 2 sa deleted %s-%s\n", src, dst);
        racoon_free(src);
        racoon_free(dst);
 
-       unbindph12(iph2);
-       remph2(iph2);
-       delph2(iph2);
+       ike_session_unlink_phase2(iph2);
 
        return;
 }
@@ -2693,106 +2306,97 @@ isakmp_ph2delete(iph2)
  * if phase1 has been finished, begin phase2.
  */
 int
-isakmp_post_acquire(iph2)
-       struct ph2handle *iph2;
+isakmp_post_acquire(phase2_handle_t *iph2)
 {
        struct remoteconf *rmconf;
-       struct ph1handle *iph1 = NULL;
+       phase1_handle_t *iph1 = NULL;
        
-       plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n");
+       plog(ASL_LEVEL_DEBUG, "In post_acquire\n");
 
        /* search appropreate configuration with masking port. */
        rmconf = getrmconf(iph2->dst);
        if (rmconf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "no configuration found for %s.\n",
+               plog(ASL_LEVEL_ERR, 
+                       "No configuration found for %s.\n",
                        saddrwop2str((struct sockaddr *)iph2->dst));
                return -1;
        }
-
        /* if passive mode, ignore the acquire message */
        if (rmconf->passive) {
-               plog(LLV_DEBUG, LOCATION, NULL,
-                       "because of passive mode, "
-                       "ignore the acquire message for %s.\n",
+               plog(ASL_LEVEL_DEBUG, 
+                       "Because of passive mode, ignore the acquire message for %s.\n",
                        saddrwop2str((struct sockaddr *)iph2->dst));
                return 0;
        }
 
-       if (ike_session_verify_ph2_parent_session(iph2)) {
-               plog(LLV_INFO, LOCATION, iph2->dst,
-                        "request for establishing IPsec-SA was ignored "
-                        "because there was a failure verifying parent session.\n");
-               return -1;
-       }
-
-       // what if there is another ph2 that is negotiating
-       if (ike_session_has_other_negoing_ph2(iph2->parent_session, iph2)) {
-               // TODO: postpone this rekey for a second later
-               plog(LLV_INFO, LOCATION, iph2->dst,
-                        "request for establishing IPsec-SA was ignored "
-                        "due to another negoing ph2.\n");
-               return -1;
-       }
+    
+    // what if there is another ph2 that is negotiating
+    if (ike_session_has_other_negoing_ph2(iph2->parent_session, iph2)) {
+        // TODO: postpone this rekey for a second later
+        plog(ASL_LEVEL_INFO,
+             "Request for establishing IPsec-SA was ignored due to another negoing ph2.\n");
+        return -1;
+    }
 
     // if this is a phase2 rekeys (the policy may not have the current port number).
     // so, use the appropriate ports.
     if (iph2->is_rekey) {
         ike_session_update_ph2_ports(iph2);
     }
+    if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1)
+        iph1 = ike_session_update_ph2_ph1bind(iph2);
+       else
+               iph1 = ike_session_get_established_or_negoing_ph1(iph2->parent_session);
 
-       iph1 = ike_session_update_ph2_ph1bind(iph2);
-
-       /* no ISAKMP-SA found. */
+       /* no IKE-SA found. */
        if (iph1 == NULL) {
-               struct sched *sc;
-
                iph2->retry_checkph1 = lcconf->retry_checkph1;
-               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((struct sockaddr *)iph2->dst));
-
-               // exit if there is another ph1 that is established (with a pending rekey timer)
-               if (ike_session_has_negoing_ph1(iph2->parent_session)) {
-                       plog(LLV_INFO, LOCATION, iph2->dst,
-                                "request for phase1 was ignored "
-                                "due to another negotiating ph1.\n");
-                       return 0;
-               }
-
+        
                /* start phase 1 negotiation as a initiator. */
-               if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src, 0) < 0) {
-                       plog(LLV_INFO, LOCATION, iph2->dst,
-                                "request for phase1 failed. will try later.\n");
+        {
+            sched_new(1, isakmp_chkph1there_stub, iph2);
+            
+            plog(ASL_LEVEL_INFO,
+                 "IPsec-SA request for %s queued due to no Phase 1 found.\n",
+                 saddrwop2str((struct sockaddr *)iph2->dst));
+            
+            // exit if there is another ph1 that is established (with a pending rekey timer)
+            if (ike_session_has_negoing_ph1(iph2->parent_session)) {
+                plog(ASL_LEVEL_INFO,
+                     "Request for Phase 1 was ignored due to another negotiating Phase 1.\n");
+                return 0;
+            }
+            
+                       if (ikev1_ph1begin_i(iph2->parent_session, rmconf, iph2->dst, iph2->src, 0) < 0) {
+                               plog(ASL_LEVEL_INFO,
+                                        "Request for Phase 1 failed. Will try later.\n");
+                       }
                }
-
                return 0;
                /*NOTREACHED*/
        }
+    
 
        /* found ISAKMP-SA, but on negotiation. */
-       if (iph1->status != PHASE1ST_ESTABLISHED) {
+       if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
                iph2->retry_checkph1 = lcconf->retry_checkph1;
                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");
+               plog(ASL_LEVEL_INFO,
+                       "Request for establishing IPsec-SA was queued due to no phase1 found.\n");
                return 0;
                /*NOTREACHED*/
        }
 
        /* found established ISAKMP-SA */
-       /* i.e. iph1->status == PHASE1ST_ESTABLISHED */
 
        /* found ISAKMP-SA. */
-       plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
 
        /* begin quick mode */
-       if (isakmp_ph2begin_i(iph1, iph2))
-               return -1;
-
+    {
+               plog(ASL_LEVEL_DEBUG, "Begin QUICK mode.\n");
+               if (ikev1_ph2begin_i(iph1, iph2))
+                       return -1;
+       }
        return 0;
 }
 
@@ -2800,32 +2404,41 @@ isakmp_post_acquire(iph2)
  * receive GETSPI from kernel.
  */
 int
-isakmp_post_getspi(iph2)
-       struct ph2handle *iph2;
+isakmp_post_getspi(phase2_handle_t *iph2)
 {
 #ifdef ENABLE_STATS
        struct timeval start, end;
 #endif
-
-       /* don't process it because there is no suitable phase1-sa. */
-       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");
-               return -1;
-       }
-
+    int error = 0;
+    
+    /* don't process it because there is no suitable phase1-sa. */
+    if (FSM_STATE_IS_EXPIRED(iph2->ph1->status)) {
+        plog(ASL_LEVEL_ERR,
+             "the negotiation is stopped, "
+             "because there is no suitable ISAKMP-SA.\n");
+        return -1;
+    }
+    fsm_set_state(&iph2->status, iph2->side == INITIATOR ? 
+                  IKEV1_STATE_QUICK_I_GETSPIDONE : IKEV1_STATE_QUICK_R_GETSPIDONE);
+    
 #ifdef ENABLE_STATS
-       gettimeofday(&start, NULL);
-#endif
-       if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
-                       [iph2->side]
-                       [iph2->status])(iph2, NULL) != 0)
+    gettimeofday(&start, NULL);
+#endif
+    switch (iph2->side) {
+        case INITIATOR:
+            error = quick_i1send(iph2, NULL);
+            break;
+        case RESPONDER:
+            error = quick_r2send(iph2, NULL);
+            break;
+    }
+
+       if (error)  //%%%%%%%% log something ???
                return -1;
 #ifdef ENABLE_STATS
        gettimeofday(&end, NULL);
-       syslog(LOG_NOTICE, "%s(%s): %8.6f",
-               "phase2",
+       plog(ASL_LEVEL_NOTICE, "%s(%s): %8.6f",
+               "Phase 2",
                s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
                timedelta(&start, &end));
 #endif
@@ -2838,47 +2451,44 @@ void
 isakmp_chkph1there_stub(p)
        void *p;
 {
-       isakmp_chkph1there((struct ph2handle *)p);
+       isakmp_chkph1there((phase2_handle_t *)p);
 }
 
 void
 isakmp_chkph1there(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 
-       if (iph2->status != PHASE2ST_STATUS2 ||
-               iph2->is_dying) {
-               plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: ph2 handle has advanced too far (status %d, STATUS2 %d, dying %d)... ignoring\n", iph2->status, PHASE2ST_STATUS2, iph2->is_dying);
+       if ((iph2->version == ISAKMP_VERSION_NUMBER_IKEV1 && iph2->status != IKEV1_STATE_QUICK_I_START) ||
+           iph2->is_dying) {
+               plog(ASL_LEVEL_DEBUG, "CHKPH1THERE: ph2 handle has advanced too far (status %d, START %d, dying %d)... ignoring\n", iph2->status, IKEV1_STATE_QUICK_I_START, iph2->is_dying);
                return;
        }
 
        iph2->retry_checkph1--;
-       if (iph2->retry_checkph1 < 0 ||
-               ike_session_verify_ph2_parent_session(iph2)) {
+
+       if (iph2->retry_checkph1 < 0 /* %%%%||
+               ike_session_verify_ph2_parent_session(iph2) */) {
                if (iph2->retry_checkph1 < 0) {
-                       plog(LLV_ERROR, LOCATION, iph2->dst,
-                                "phase2 negotiation failed "
-                                "due to time up waiting for phase1. %s\n",
+                       plog(ASL_LEVEL_ERR,
+                                "Phase 2 negotiation failed "
+                                "due to time up waiting for Phase 1. %s\n",
                                 sadbsecas2str(iph2->dst, iph2->src,
                                                           iph2->satype, 0, 0));
                } else {
-                       plog(LLV_ERROR, LOCATION, iph2->dst,
-                                "phase2 negotiation failed "
+                       plog(ASL_LEVEL_ERR,
+                                "Phase 2 negotiation failed "
                                 "due to invalid parent session. %s\n",
                                 sadbsecas2str(iph2->dst, iph2->src,
                                                           iph2->satype, 0, 0));
                }
-               plog(LLV_INFO, LOCATION, NULL,
-                       "delete phase 2 handler.\n");
+               plog(ASL_LEVEL_INFO, 
+                       "delete Phase 2 handler.\n");
 
                /* send acquire to kernel as error */
                pk_sendeacquire(iph2);
-
-               unbindph12(iph2);
-               remph2(iph2);
-               delph2(iph2);
-
+               ike_session_unlink_phase2(iph2);
                return;
        }
 
@@ -2887,39 +2497,44 @@ isakmp_chkph1there(iph2)
        /* XXX Even if ph1 as responder is there, should we not start
         * phase 2 negotiation ? */
        if (iph1 != NULL
-        && iph1->status == PHASE1ST_ESTABLISHED) {
+        && FSM_STATE_IS_ESTABLISHED(iph1->status)) {
                /* found isakmp-sa */
 
-               plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
-               plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str((struct sockaddr *)iph1->local));
-               plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str((struct sockaddr *)iph1->remote));
-               plog(LLV_DEBUG2, LOCATION, NULL, "before:\n");
-               plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str((struct sockaddr *)iph2->src));
-               plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str((struct sockaddr *)iph2->dst));
+               plog(ASL_LEVEL_DEBUG, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
+               plog(ASL_LEVEL_DEBUG, "iph1->local: %s\n", saddr2str((struct sockaddr *)iph1->local));
+               plog(ASL_LEVEL_DEBUG, "iph1->remote: %s\n", saddr2str((struct sockaddr *)iph1->remote));
+               plog(ASL_LEVEL_DEBUG, "before:\n");
+               plog(ASL_LEVEL_DEBUG, "src: %s\n", saddr2str((struct sockaddr *)iph2->src));
+               plog(ASL_LEVEL_DEBUG, "dst: %s\n", saddr2str((struct sockaddr *)iph2->dst));
                set_port(iph2->src, extract_port(iph1->local));
                set_port(iph2->dst, extract_port(iph1->remote));
-               plog(LLV_DEBUG2, LOCATION, NULL, "After:\n");
-               plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str((struct sockaddr *)iph2->src));
-               plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str((struct sockaddr *)iph2->dst));
+               plog(ASL_LEVEL_DEBUG, "After:\n");
+               plog(ASL_LEVEL_DEBUG, "src: %s\n", saddr2str((struct sockaddr *)iph2->src));
+               plog(ASL_LEVEL_DEBUG, "dst: %s\n", saddr2str((struct sockaddr *)iph2->dst));
 
                /* begin quick mode */
-               if (isakmp_ph2begin_i(iph1, iph2)) {
-                       unbindph12(iph2);
-                       remph2(iph2);
-                       delph2(iph2);
+        {
+                       if (ikev1_ph2begin_i(iph1, iph2)) {
+                               ike_session_unlink_phase2(iph2);
+                       }
                }
                return;
        }
        if (!ike_session_has_negoing_ph1(iph2->parent_session)) {
                struct remoteconf *rmconf = getrmconf(iph2->dst);
                /* start phase 1 negotiation as a initiator. */
-               if (rmconf == NULL ||
-                   isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src, 0) < 0) {
-                       plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established/negoing ph1 handler found... failed to initiate new one\n");
+               if (rmconf) {
+            {
+                               if (ikev1_ph1begin_i(iph2->parent_session, rmconf, iph2->dst, iph2->src, 0) < 0) {
+                                       plog(ASL_LEVEL_DEBUG, "CHKPH1THERE: no established/negoing ph1 handler found... failed to initiate new one\n");
+                               }
+                       }                       
+               } else if (rmconf == NULL) {
+                       plog(ASL_LEVEL_DEBUG, "CHKPH1THERE: no remoteconf found... failed to initiate new one\n");
                }
        }
 
-       plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
+       plog(ASL_LEVEL_DEBUG, "CHKPH1THERE: no established ph1 handler found\n");
 
        /* no isakmp-sa found */
        sched_new(1, isakmp_chkph1there_stub, iph2);
@@ -2982,7 +2597,7 @@ isakmp_add_attr_v(buf0, type, val, len)
        } else
                buf = vmalloc(tlen);
        if (!buf) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get a attribute buffer.\n");
                return NULL;
        }
@@ -3015,7 +2630,7 @@ isakmp_add_attr_l(buf0, type, val)
        } else
                buf = vmalloc(tlen);
        if (!buf) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get a attribute buffer.\n");
                return NULL;
        }
@@ -3047,7 +2662,7 @@ isakmp_newcookie(place, remote, local)
 
 
        if (remote->ss_family != local->ss_family) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "address family mismatch, remote:%d local:%d\n",
                        remote->ss_family, local->ss_family);
                goto end;
@@ -3066,7 +2681,7 @@ isakmp_newcookie(place, remote, local)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "invalid family: %d\n", remote->ss_family);
                goto end;
        }
@@ -3074,7 +2689,7 @@ isakmp_newcookie(place, remote, local)
                + sizeof(time_t) + lcconf->secret_size;
        buf = vmalloc(blen);
        if (buf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get a cookie.\n");
                goto end;
        }
@@ -3111,7 +2726,7 @@ isakmp_newcookie(place, remote, local)
        memcpy(place, buf2->v, sizeof(cookie_t));
 
        sa1 = val2str(place, sizeof (cookie_t));
-       plog(LLV_DEBUG, LOCATION, NULL, "new cookie:\n%s\n", sa1);
+       plog(ASL_LEVEL_DEBUG, "new cookie:\n%s\n", sa1);
        racoon_free(sa1);
 
        error = 0;
@@ -3133,13 +2748,13 @@ isakmp_p2ph(buf, gen)
 {
        /* XXX to be checked in each functions for logging. */
        if (*buf) {
-               plog(LLV_WARNING, LOCATION, NULL,
+               plog(ASL_LEVEL_WARNING, 
                        "ignore this payload, same payload type exist.\n");
                return -1;
        }
 
        if (ntohs(gen->len) < sizeof(*gen)) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "ignore this payload, invalid payload len %d.\n",
                         ntohs(gen->len));
                return -1;
@@ -3147,7 +2762,7 @@ isakmp_p2ph(buf, gen)
 
        *buf = vmalloc(ntohs(gen->len) - sizeof(*gen));
        if (*buf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get buffer.\n");
                return -1;
        }
@@ -3158,13 +2773,13 @@ isakmp_p2ph(buf, gen)
 
 u_int32_t
 isakmp_newmsgid2(iph1)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 {
        u_int32_t msgid2;
 
        do {
                msgid2 = eay_random();
-       } while (getph2bymsgid(iph1, msgid2));
+       } while (ike_session_getph2bymsgid(iph1, msgid2));
 
        return msgid2;
 }
@@ -3175,7 +2790,7 @@ isakmp_newmsgid2(iph1)
 static caddr_t
 set_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid)
        vchar_t *vbuf;
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        int nptype;
        u_int8_t etype;
        u_int8_t flags;
@@ -3206,7 +2821,7 @@ set_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid)
 caddr_t
 set_isakmp_header1(vbuf, iph1, nptype)
        vchar_t *vbuf;
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        int nptype;
 {
        return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid);
@@ -3218,7 +2833,7 @@ set_isakmp_header1(vbuf, iph1, nptype)
 caddr_t
 set_isakmp_header2(vbuf, iph2, nptype)
        vchar_t *vbuf;
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        int nptype;
 {
        return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid);
@@ -3236,7 +2851,7 @@ set_isakmp_payload(buf, src, nptype)
        struct isakmp_gen *gen;
        caddr_t p = buf;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "add payload of len %zu, next type %d\n",
+       plog(ASL_LEVEL_DEBUG, "add payload of len %zu, next type %d\n",
            src->l, nptype);
 
        gen = (struct isakmp_gen *)p;
@@ -3249,46 +2864,17 @@ set_isakmp_payload(buf, src, nptype)
        return p;
 }
 
-static int
-etypesw1(etype)
-       int etype;
-{
-       switch (etype) {
-       case ISAKMP_ETYPE_IDENT:
-               return 1;
-       case ISAKMP_ETYPE_AGG:
-               return 2;
-       case ISAKMP_ETYPE_BASE:
-               return 3;
-       default:
-               return 0;
-       }
-       /*NOTREACHED*/
-}
-
-static int
-etypesw2(etype)
-       int etype;
-{
-       switch (etype) {
-       case ISAKMP_ETYPE_QUICK:
-               return 1;
-       default:
-               return 0;
-       }
-       /*NOTREACHED*/
-}
 
 #ifdef HAVE_PRINT_ISAKMP_C
 /* for print-isakmp.c */
 char *snapend;
-extern void isakmp_print __P((const u_char *, u_int, const u_char *));
+extern void isakmp_print(const u_char *, u_int, const u_char *);
 
-char *getname __P((const u_char *));
+char *getname(const u_char *);
 #ifdef INET6
-char *getname6 __P((const u_char *));
+char *getname6(const u_char *);
 #endif
-int safeputchar __P((int));
+int safeputchar(int);
 
 /*
  * Return a name for the IP address pointed to by ap.  This address
@@ -3367,11 +2953,11 @@ isakmp_printpacket(msg, from, my, decoded)
        vchar_t *buf;
 #endif
 
-       if (loglevel < LLV_DEBUG)
+       if (loglevel < ASL_LEVEL_DEBUG)
                return;
 
 #ifdef YIPS_DEBUG
-       plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
+       plog(ASL_LEVEL_DEBUG, "begin.\n");
 
        gettimeofday(&tv, NULL);
        s = tv.tv_sec % 3600;
@@ -3431,16 +3017,16 @@ isakmp_printpacket(msg, from, my, decoded)
 
 int
 copy_ph1addresses(iph1, rmconf, remote, local)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        struct remoteconf *rmconf;
        struct sockaddr_storage *remote, *local;
 {
        u_short *port = NULL;
 
        /* address portion must be grabbed from real remote address "remote" */
-       iph1->remote = dupsaddr((struct sockaddr *)remote);
+       iph1->remote = dupsaddr(remote);
        if (iph1->remote == NULL) {
-               delph1(iph1);
+               ike_session_delph1(iph1);
                return -1;
        }
 
@@ -3473,18 +3059,18 @@ copy_ph1addresses(iph1, rmconf, remote, local)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "invalid family: %d\n", iph1->remote->ss_family);
-               delph1(iph1);
+               ike_session_delph1(iph1);
                return -1;
        }
 
        if (local == NULL)
                iph1->local = getlocaladdr((struct sockaddr *)iph1->remote);
        else
-               iph1->local = dupsaddr((struct sockaddr *)local);
+               iph1->local = dupsaddr(local);
        if (iph1->local == NULL) {
-               delph1(iph1);
+               ike_session_delph1(iph1);
                return -1;
        }
        port = NULL;
@@ -3510,14 +3096,14 @@ copy_ph1addresses(iph1, rmconf, remote, local)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "invalid family: %d\n", iph1->local->ss_family);
-               delph1(iph1);
+               ike_session_delph1(iph1);
                return -1;
        }
 #ifdef ENABLE_NATT
        if ( port != NULL && *port == htons(lcconf->port_isakmp_natt) ) {
-           plog (LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n");
+           plog (ASL_LEVEL_DEBUG, "Marking ports as changed\n");
            iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER;
        }
 #endif
@@ -3525,29 +3111,9 @@ copy_ph1addresses(iph1, rmconf, remote, local)
        return 0;
 }
 
-static int
-nostate1(iph1, msg)
-       struct ph1handle *iph1;
-       vchar_t *msg;
-{
-       plog(LLV_ERROR, LOCATION, iph1->remote, "wrong state %u.\n",
-                       iph1->status);
-       return -1;
-}
-
-static int
-nostate2(iph2, msg)
-       struct ph2handle *iph2;
-       vchar_t *msg;
-{
-       plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "wrong state %u.\n",
-               iph2->status);
-       return -1;
-}
-
 void
 log_ph1established(iph1)
-       const struct ph1handle *iph1;
+       const phase1_handle_t *iph1;
 {
        char *src, *dst;
 
@@ -3556,18 +3122,15 @@ log_ph1established(iph1)
        STRDUP_FATAL(src);
        STRDUP_FATAL(dst);
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO, 
                "ISAKMP-SA established %s-%s spi:%s\n",
                src, dst,
                isakmp_pindex(&iph1->index, 0));
-       EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
-       if(!iph1->rmconf->mode_cfg)
-               EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
 
        racoon_free(src);
        racoon_free(dst);
 
-       IPSECLOGASLMSG("IPSec Phase1 established (Initiated by %s).\n",
+       IPSECLOGASLMSG("IPSec Phase 1 established (Initiated by %s).\n",
                                   (iph1->side == INITIATOR)? "me" : "peer");
 
        return;
@@ -3594,7 +3157,7 @@ isakmp_plist_append (struct payload_list *plist, vchar_t *payload, int payload_t
 }
 
 vchar_t * 
-isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
+isakmp_plist_set_all (struct payload_list **plist, phase1_handle_t *iph1)
 {
        struct payload_list *ptr = *plist, *first;
        size_t tlen = sizeof (struct isakmp), n = 0;
@@ -3613,7 +3176,7 @@ isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
 
        buf = vmalloc(tlen);
        if (buf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get buffer to send.\n");
                goto end;
        }
@@ -3644,197 +3207,45 @@ end:
 }
 
 #ifdef ENABLE_FRAG
-int 
+void
 frag_handler(iph1, msg, remote, local)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        vchar_t *msg;
        struct sockaddr_storage *remote;
        struct sockaddr_storage *local;
 {
        vchar_t *newmsg;
-    int result;
 
        if (isakmp_frag_extract(iph1, msg) == 1) {
                if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
-                       plog(LLV_ERROR, LOCATION, remote, 
+                       plog(ASL_LEVEL_ERR,  
                            "Packet reassembly failed\n");
-                       return -1;
+                       return;
                }
 
                /* simply reply if the packet was processed. */
-               if (check_recvdpkt(remote, local, newmsg) > 0) {
+               if (ike_session_check_recvdpkt(remote, local, newmsg) > 0) {
                        IPSECLOGASLMSG("Received (reassembled) retransmitted packet from %s.\n",
                                                   saddr2str((struct sockaddr *)remote));
 
-                       plog(LLV_NOTIFY, LOCATION, NULL,
+                       plog(ASL_LEVEL_NOTICE, 
                                 "the reassembled packet is retransmitted by %s.\n",
                                 saddr2str((struct sockaddr *)remote));
-            vfree(newmsg);  
-                       return 0;
+            vfree(newmsg);
+                       return;
                }
 
-               result = isakmp_main(newmsg, remote, local);
+               isakmp_main(newmsg, remote, local);
         vfree(newmsg);
-        return result;
-       }
-
-       return 0;
-}
-#endif
-
-void
-script_hook(iph1, script)
-       struct ph1handle *iph1;
-       int script;
-{
-#define IP_MAX 40
-#define PORT_MAX 6
-       char addrstr[IP_MAX];
-       char portstr[PORT_MAX];
-       char **envp = NULL;
-       int envc = 1;
-       struct sockaddr_in *sin;
-       char **c;
-
-       if (iph1 == NULL ||
-               iph1->rmconf == NULL ||
-               iph1->rmconf->script[script] == NULL)
-               return;
-
-#ifdef ENABLE_HYBRID
-       (void)isakmp_cfg_setenv(iph1, &envp, &envc);
-#endif
-
-       /* local address */
-       sin = (struct sockaddr_in *)iph1->local;
-       inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
-       snprintf(portstr, sizeof(portstr), "%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");
-               goto out;
-       }
-
-       if (script_env_append(&envp, &envc, "LOCAL_PORT", portstr) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_PORT\n");
-               goto out;
-       }
-
-       /* Peer address */
-       if (iph1->remote != NULL) {
-               sin = (struct sockaddr_in *)iph1->remote;
-               inet_ntop(sin->sin_family, &sin->sin_addr, addrstr, IP_MAX);
-               snprintf(portstr, sizeof(portstr), "%d", ntohs(sin->sin_port));
-
-               if (script_env_append(&envp, &envc, 
-                   "REMOTE_ADDR", addrstr) != 0) {
-                       plog(LLV_ERROR, LOCATION, NULL, 
-                           "Cannot set REMOTE_ADDR\n");
-                       goto out;
-               }
-
-               if (script_env_append(&envp, &envc, 
-                   "REMOTE_PORT", portstr) != 0) {
-                       plog(LLV_ERROR, LOCATION, NULL, 
-                           "Cannot set REMOTEL_PORT\n");
-                       goto out;
-               }
        }
 
-#ifdef HAVE_OPENSSL
-       if (privsep_script_exec(iph1->rmconf->script[script]->v, 
-           script, envp) != 0) 
-               plog(LLV_ERROR, LOCATION, NULL, 
-                   "Script %s execution failed\n", script_names[script]);
-#else
-       if (script_exec(iph1->rmconf->script[script]->v, 
-                                                       script, envp) != 0) 
-               plog(LLV_ERROR, LOCATION, NULL, 
-                        "Script %s execution failed\n", script_names[script]); 
-#endif
-       
-out:
-       for (c = envp; *c; c++)
-               racoon_free(*c);
-
-       racoon_free(envp);
-
        return;
 }
-
-int
-script_env_append(envp, envc, name, value)
-       char ***envp;
-       int *envc;
-       char *name;
-       char *value;
-{
-       char *envitem;
-       char **newenvp;
-       int newenvc;
-       int envitem_len;
-
-       envitem_len = strlen(name) + 1 + strlen(value) + 1;
-       envitem = racoon_malloc(envitem_len);
-       if (envitem == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "Cannot allocate memory: %s\n", strerror(errno));
-               return -1;
-       }
-       snprintf(envitem, envitem_len, "%s=%s", name, value);
-
-       newenvc = (*envc) + 1;
-       newenvp = racoon_realloc(*envp, newenvc * sizeof(char *));
-       if (newenvp == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "Cannot allocate memory: %s\n", strerror(errno));
-               racoon_free(envitem);
-               return -1;
-       }
-
-       newenvp[newenvc - 2] = envitem;
-       newenvp[newenvc - 1] = NULL;
-
-       *envp = newenvp;
-       *envc = newenvc;
-       return 0;
-}
-
-int
-script_exec(script, name, envp)
-       char *script;
-       int name;
-       char *const envp[];
-{
-       char *argv[] = { NULL, NULL, NULL };
-
-       argv[0] = script;
-       argv[1] = script_names[name];
-       argv[2] = NULL;
-
-       switch (fork()) { 
-       case 0:
-               execve(argv[0], argv, envp);
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "execve(\"%s\") failed: %s\n",
-                   argv[0], strerror(errno));
-               _exit(1);
-               break;
-       case -1:
-               plog(LLV_ERROR, LOCATION, NULL,
-                   "Cannot fork: %s\n", strerror(errno));
-               return -1;
-               break;
-       default:
-               break;
-       }       
-
-       return 0;
-}
+#endif
 
 void
 purge_remote(iph1)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
 {
        vchar_t *buf = NULL;
        struct sadb_msg *msg, *next, *end;
@@ -3842,15 +3253,15 @@ purge_remote(iph1)
        struct sockaddr_storage *src, *dst;
        caddr_t mhp[SADB_EXT_MAX + 1];
        u_int proto_id;
-       struct ph2handle *iph2;
-       struct ph1handle *new_iph1;
+       phase2_handle_t *iph2;
+       phase1_handle_t *new_iph1;
 
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO, 
                 "purging ISAKMP-SA spi=%s.\n",
                 isakmp_pindex(&(iph1->index), iph1->msgid));
 
        /* Mark as expired. */
-       iph1->status = PHASE1ST_EXPIRED;
+       fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
 
        new_iph1 = ike_session_update_ph1_ph2tree(iph1);
 
@@ -3860,7 +3271,7 @@ purge_remote(iph1)
         */
        buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
        if (buf == NULL) {
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG, 
                        "pfkey_dump_sadb returned nothing.\n");
                return;
        }
@@ -3878,7 +3289,7 @@ purge_remote(iph1)
                }
 
                if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "pfkey_check (%s)\n", ipsec_strerror());
                        msg = next;
                        continue;
@@ -3913,14 +3324,14 @@ purge_remote(iph1)
                }
 
                proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
-               iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
+               iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
 
                /* Check if there is another valid ISAKMP-SA */
                if (new_iph1 != NULL) {
 
                        if (iph2 == NULL) {
                                /* No handler... still send a pfkey_delete message, but log this !*/
-                               plog(LLV_INFO, LOCATION, NULL,
+                               plog(ASL_LEVEL_INFO, 
                                        "Unknown IPsec-SA spi=%u, hmmmm?\n",
                                        ntohl(sa->sadb_sa_spi));
                        }else{
@@ -3935,10 +3346,9 @@ purge_remote(iph1)
                                }
 
                                /* If the ph2handle is established, do not purge IPsec-SA */
-                               if (iph2->status == PHASE2ST_ESTABLISHED ||
-                                       iph2->status == PHASE2ST_EXPIRED) {
+                               if (FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(iph2->status)) {
                                        
-                                       plog(LLV_INFO, LOCATION, NULL,
+                                       plog(ASL_LEVEL_INFO, 
                                                 "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n",
                                                 ntohl(sa->sadb_sa_spi),
                                                 isakmp_pindex(&(new_iph1->index), new_iph1->msgid));
@@ -3957,12 +3367,10 @@ purge_remote(iph1)
                /* delete a relative phase 2 handle. */
                if (iph2 != NULL) {
                        delete_spd(iph2);
-                       unbindph12(iph2);
-                       remph2(iph2);
-                       delph2(iph2);
+                       ike_session_unlink_phase2(iph2);
                }
 
-               plog(LLV_INFO, LOCATION, NULL,
+               plog(ASL_LEVEL_INFO, 
                         "purged IPsec-SA spi=%u.\n",
                         ntohl(sa->sadb_sa_spi));
 
@@ -3973,7 +3381,7 @@ purge_remote(iph1)
                vfree(buf);
 
        /* Mark the phase1 handler as EXPIRED */
-       plog(LLV_INFO, LOCATION, NULL,
+       plog(ASL_LEVEL_INFO, 
                 "purged ISAKMP-SA spi=%s.\n",
                 isakmp_pindex(&(iph1->index), iph1->msgid));
 
@@ -3984,7 +3392,7 @@ purge_remote(iph1)
 
 void 
 delete_spd(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        if (iph2 == NULL)
                return;
@@ -4003,7 +3411,7 @@ delete_spd(iph2)
                int error;
                int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */
 
-               plog(LLV_INFO, LOCATION, NULL,
+               plog(ASL_LEVEL_INFO, 
                         "generated policy, deleting it.\n");
                
                memset(&u.spidx, 0, sizeof(u.spidx));
@@ -4032,7 +3440,7 @@ delete_spd(iph2)
                        || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
                        /* get a destination address of a policy */
                        error = ipsecdoi_id2sockaddr(iph2->id, &u.spidx.dst,
-                           &u.spidx.prefd, &u.spidx.ul_proto);
+                           &u.spidx.prefd, &u.spidx.ul_proto, iph2->version);
                        if (error)
                                goto purge;
                        
@@ -4056,9 +3464,9 @@ delete_spd(iph2)
                        
                } else {
                        
-                       plog(LLV_DEBUG, LOCATION, NULL,
-                                "get a destination address of SP index "
-                                "from phase1 address "
+                       plog(ASL_LEVEL_DEBUG, 
+                                "Get a destination address of SP index "
+                                "from Phase 1 address "
                                 "due to no ID payloads found "
                                 "OR because ID type is not address.\n");
                        
@@ -4093,7 +3501,7 @@ delete_spd(iph2)
                        || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
                        /* get a source address of inbound SA */
                        error = ipsecdoi_id2sockaddr(iph2->id_p, &u.spidx.src,
-                           &u.spidx.prefs, &u.spidx.ul_proto);
+                           &u.spidx.prefs, &u.spidx.ul_proto, iph2->version);
                        if (error)
                                goto purge;
 
@@ -4114,15 +3522,15 @@ delete_spd(iph2)
                        if (_XIDT(iph2->id_p) == idi2type
                                && u.spidx.dst.ss_family == u.spidx.src.ss_family) {
                                iph2->src_id = 
-                                   dupsaddr((struct sockaddr *)&u.spidx.dst);
+                                   dupsaddr(&u.spidx.dst);
                                iph2->dst_id = 
-                                   dupsaddr((struct sockaddr *)&u.spidx.src);
+                                   dupsaddr(&u.spidx.src);
                        }
 
                } else {
-                       plog(LLV_DEBUG, LOCATION, NULL,
-                                "get a source address of SP index "
-                                "from phase1 address "
+                       plog(ASL_LEVEL_DEBUG, 
+                                "Get a source address of SP index "
+                                "from Phase 1 address "
                                 "due to no ID payloads found "
                                 "OR because ID type is not address.\n");
 
@@ -4147,12 +3555,12 @@ delete_spd(iph2)
 
 #undef _XIDT
 
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG, 
                         "get a src address from ID payload "
                         "%s prefixlen=%u ul_proto=%u\n",
                         saddr2str((struct sockaddr *)&u.spidx.src),
                         u.spidx.prefs, u.spidx.ul_proto);
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG, 
                         "get dst address from ID payload "
                         "%s prefixlen=%u ul_proto=%u\n",
                         saddr2str((struct sockaddr *)&u.spidx.dst),
@@ -4171,10 +3579,10 @@ delete_spd(iph2)
                 */
 
                if (pk_sendspddelete(iph2) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "pfkey spddelete(inbound) failed.\n");
                }else{
-                       plog(LLV_DEBUG, LOCATION, NULL,
+                       plog(ASL_LEVEL_DEBUG, 
                                 "pfkey spddelete(inbound) sent.\n");
                }
 
@@ -4183,10 +3591,10 @@ delete_spd(iph2)
                if (tunnel_mode_prop(iph2->approval)) {
                        u.spidx.dir = IPSEC_DIR_FWD;
                        if (pk_sendspddelete(iph2) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                         "pfkey spddelete(forward) failed.\n");
                        }else{
-                               plog(LLV_DEBUG, LOCATION, NULL,
+                               plog(ASL_LEVEL_DEBUG, 
                                         "pfkey spddelete(forward) sent.\n");
                        }
                }
@@ -4204,10 +3612,10 @@ delete_spd(iph2)
                u.spidx.prefd = pref;
 
                if (pk_sendspddelete(iph2) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "pfkey spddelete(outbound) failed.\n");
                }else{
-                       plog(LLV_DEBUG, LOCATION, NULL,
+                       plog(ASL_LEVEL_DEBUG, 
                                 "pfkey spddelete(outbound) sent.\n");
                }
 purge:
@@ -4232,13 +3640,13 @@ setscopeid(sp_addr0, sa_addr0)
 
        /* this check should not be here ? */
        if (sa_addr->sin6_family != AF_INET6) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "can't get scope ID: family mismatch\n");
                return -1;
        }
 
        if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "scope ID is not supported except of lladdr.\n");
                return -1;
        }
@@ -4251,10 +3659,10 @@ setscopeid(sp_addr0, sa_addr0)
 
 vchar_t *
 isakmp_plist_append_initial_contact (iph1, plist)
-       struct ph1handle *iph1;
+       phase1_handle_t *iph1;
        struct payload_list *plist;
 {
-       if (!iph1->is_rekey && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
+       if (!iph1->is_rekey && iph1->rmconf->ini_contact && !ike_session_getcontacted(iph1->remote)) {
                vchar_t *notp_ini = NULL;
                struct isakmp_pl_n np, *nptr;
                char *cptr;
@@ -4270,25 +3678,24 @@ isakmp_plist_append_initial_contact (iph1, plist)
                        cptr = notp_ini->v + sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen);
                        memcpy(cptr, &iph1->index, sizeof(isakmp_index));
                        plist = isakmp_plist_append(plist, notp_ini, ISAKMP_NPTYPE_N);
-                       plog(LLV_DEBUG2, LOCATION, iph1->remote,
+                       plog(ASL_LEVEL_DEBUG,
                                 "added initial-contact payload.\n");
                        
                        /* insert a node into contacted list. */
-                       if (inscontacted(iph1->remote) == -1) {
-                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                       if (ike_session_inscontacted(iph1->remote) == -1) {
+                               plog(ASL_LEVEL_ERR,
                                         "failed to add contacted list.\n");
                                /* ignore */
                        }
                        return notp_ini;
                } else {
-                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to allocate notification payload.\n");
                        return NULL;
                }
        } else {
-               plog(LLV_DEBUG, LOCATION, iph1->remote,
-                        "failed to add initial-contact payload: rekey %d, ini-contact %d, contacted %d.\n",
-                        iph1->is_rekey? 1:0, iph1->rmconf->ini_contact, getcontacted(iph1->remote)? 1:0);
+               plog(ASL_LEVEL_DEBUG, "failed to add initial-contact payload: rekey %d, ini-contact %d, contacted %d.\n",
+                        iph1->is_rekey? 1:0, iph1->rmconf->ini_contact, ike_session_getcontacted(iph1->remote)? 1:0);
        }
        return NULL;
 }