]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/isakmp_quick.c
ipsec-326.81.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_quick.c
index 871072ced8a2dbf5e1c11085aa1b5c6b15f5e3ce..b31a34c1db5d8df98e62486e47b3b7a91b8ceef5 100644 (file)
@@ -53,9 +53,6 @@
 #  include <time.h>
 # endif
 #endif
-#ifdef ENABLE_HYBRID
-#include <resolv.h>
-#endif
 
 #ifndef HAVE_NETINET6_IPSEC
 #include <netinet/ipsec.h>
@@ -70,6 +67,7 @@
 #include "plog.h"
 #include "debug.h"
 
+#include "fsm.h"
 #include "localconf.h"
 #include "remoteconf.h"
 #include "handler.h"
 #include "sockmisc.h"
 #include "proposal.h"
 #include "sainfo.h"
-#include "admin.h"
 #include "strnames.h"
 #include "nattraversal.h"
 #include "ipsecSessionTracer.h"
 #include "ipsecMessageTracer.h"
+#ifndef HAVE_OPENSSL
+#include <Security/SecDH.h>
+#endif
 
 /* quick mode */
-static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
-static int get_sainfo_r __P((struct ph2handle *));
-static int get_proposal_r __P((struct ph2handle *));
-static int get_proposal_r_remote __P((struct ph2handle *, int));
+static vchar_t *quick_ir1mx (phase2_handle_t *, vchar_t *, vchar_t *);
+static int get_proposal_r_remote (phase2_handle_t *, int);
 
 /* \f%%%
  * Quick Mode
@@ -107,15 +105,15 @@ static int get_proposal_r_remote __P((struct ph2handle *, int));
  * begin Quick Mode as initiator.  send pfkey getspi message to kernel.
  */
 int
-quick_i1prep(iph2, msg)
-       struct ph2handle *iph2;
+quick_iprep(iph2, msg)
+       phase2_handle_t *iph2;
        vchar_t *msg; /* must be null pointer */
 {
        int error = ISAKMP_INTERNAL_ERROR;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_STATUS2) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_I_START) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
@@ -127,7 +125,7 @@ quick_i1prep(iph2, msg)
        if (iph2->ivm == NULL)
                return 0;
 
-       iph2->status = PHASE2ST_GETSPISENT;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_GETSPISENT);
 
        /* don't anything if local test mode. */
        if (f_local) {
@@ -137,12 +135,12 @@ quick_i1prep(iph2, msg)
 
        /* send getspi message */
        if (pk_sendgetspi(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to send getspi message");
                goto end;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey getspi sent.\n");
 
        iph2->sce = sched_new(lcconf->wait_ph2complete,
                pfkey_timeover_stub, iph2);
@@ -159,7 +157,7 @@ end:
  */
 int
 quick_i1send(iph2, msg)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        vchar_t *msg; /* must be null pointer */
 {
        vchar_t *body = NULL;
@@ -179,19 +177,19 @@ quick_i1send(iph2, msg)
 
        /* validity check */
        if (msg != NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "msg has to be NULL in this function.\n");
                goto end;
        }
-       if (iph2->status != PHASE2ST_GETSPIDONE) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_I_GETSPIDONE) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* create SA payload for my proposal */
-       if (ipsecdoi_setph2proposal(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (ipsecdoi_setph2proposal(iph2, FALSE) < 0) {
+               plog(ASL_LEVEL_ERR,
                         "failed to set proposal");
                goto end;
        }
@@ -199,7 +197,7 @@ quick_i1send(iph2, msg)
        /* generate NONCE value */
        iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
        if (iph2->nonce == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to generate NONCE");
                goto end;
        }
@@ -214,13 +212,18 @@ quick_i1send(iph2, msg)
        if (pfsgroup) {
                /* DH group settting if PFS is required. */
                if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "failed to set DH value.\n");
                        goto end;
                }
+#ifdef HAVE_OPENSSL
                if (oakley_dh_generate(iph2->pfsgrp,
-                               &iph2->dhpub, &iph2->dhpriv) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                                                          &iph2->dhpub, &iph2->dhpriv) < 0) {
+#else
+               if (oakley_dh_generate(iph2->pfsgrp,
+                               &iph2->dhpub, &iph2->publicKeySize, &iph2->dhC) < 0) {
+#endif
+                       plog(ASL_LEVEL_ERR, 
                                 "failed to generate DH");
                        goto end;
                }
@@ -228,14 +231,12 @@ quick_i1send(iph2, msg)
 
        /* generate ID value */
        if (ipsecdoi_setid2(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get ID.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n");
-       plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
-       plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n");
-       plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
+       plogdump(ASL_LEVEL_DEBUG, iph2->id->v, iph2->id->l, "IDci:\n");
+       plogdump(ASL_LEVEL_DEBUG, iph2->id_p->v, iph2->id_p->l, "IDcr:\n");
 
        /*
         * we do not attach IDci nor IDcr, under the following condition:
@@ -244,8 +245,8 @@ quick_i1send(iph2, msg)
         * - id payload suggests to encrypt all the traffic (no specific
         *   protocol type)
         */
-       id = (struct ipsecdoi_id_b *)iph2->id->v;
-       id_p = (struct ipsecdoi_id_b *)iph2->id_p->v;
+       id = ALIGNED_CAST(struct ipsecdoi_id_b *)iph2->id->v;
+       id_p = ALIGNED_CAST(struct ipsecdoi_id_b *)iph2->id_p->v;
        if (id->proto_id == 0
         && id_p->proto_id == 0
         && iph2->ph1->rmconf->support_proxy == 0
@@ -273,24 +274,22 @@ quick_i1send(iph2, msg)
                && (iph2->ph1->natt_flags & NAT_DETECTED)) {
                natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r);
                if (natoa_type == -1) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "failed to generate NAT-OA payload.\n");
                        goto end;
                } else if (natoa_type != 0) {
                        tlen += sizeof(*gen) + natoa_i->l;
                        tlen += sizeof(*gen) + natoa_r->l;
                        
-                       plog(LLV_DEBUG, LOCATION, NULL, "initiator send NAT-OAi:\n");
-                       plogdump(LLV_DEBUG, natoa_i->v, natoa_i->l);
-                       plog(LLV_DEBUG, LOCATION, NULL, "initiator send NAT-OAr:\n");
-                       plogdump(LLV_DEBUG, natoa_r->v, natoa_r->l);
+                       //plogdump(ASL_LEVEL_DEBUG, natoa_i->v, natoa_i->l, "initiator send NAT-OAi:\n");
+                       //plogdump(ASL_LEVEL_DEBUG, natoa_r->v, natoa_r->l, "initiator send NAT-OAr:\n");
                }
        }
 #endif
 
        body = vmalloc(tlen);
        if (body == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get buffer to send.\n");
                goto end;
        }
@@ -332,7 +331,7 @@ quick_i1send(iph2, msg)
        /* generate HASH(1) */
        hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
        if (hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to compute HASH");
                goto end;
        }
@@ -340,7 +339,7 @@ quick_i1send(iph2, msg)
        /* send isakmp payload */
        iph2->sendbuf = quick_ir1mx(iph2, body, hash);
        if (iph2->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to get send buffer");
                goto end;
        }
@@ -348,13 +347,13 @@ quick_i1send(iph2, msg)
        /* send the packet, add to the schedule to resend */
        iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
        if (isakmp_ph2resend(iph2) == -1) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to send packet");
                goto end;
        }
 
        /* change status of isakmp status entry */
-       iph2->status = PHASE2ST_MSG1SENT;
+    fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_MSG1SENT);
 
        error = 0;
 
@@ -390,7 +389,7 @@ end:
  */
 int
 quick_i2recv(iph2, msg0)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
@@ -403,25 +402,25 @@ quick_i2recv(iph2, msg0)
        char *p;
        int tlen;
        int error = ISAKMP_INTERNAL_ERROR;
-       struct sockaddr *natoa_i = NULL;
-       struct sockaddr *natoa_r = NULL;
+       struct sockaddr_storage *natoa_i = NULL;
+       struct sockaddr_storage *natoa_r = NULL;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_MSG1SENT) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_I_MSG1SENT) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* decrypt packet */
        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "Packet wasn't encrypted.\n");
                goto end;
        }
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
        if (msg == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to decrypt");
                goto end;
        }
@@ -435,15 +434,15 @@ quick_i2recv(iph2, msg0)
         */
        pbuf = isakmp_parse(msg);
        if (pbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to parse msg");
                goto end;
        }
-       pa = (struct isakmp_parse_t *)pbuf->v;
+       pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
 
        /* HASH payload is fixed postion */
        if (pa->type != ISAKMP_NPTYPE_HASH) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "received invalid next payload type %d, "
                        "expecting %d.\n",
                        pa->type, ISAKMP_NPTYPE_HASH);
@@ -459,7 +458,7 @@ quick_i2recv(iph2, msg0)
         */
        /* HASH payload is fixed postion */
        if (pa->type != ISAKMP_NPTYPE_SA) {
-               plog(LLV_WARNING, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_WARNING,
                        "received invalid next payload type %d, "
                        "expecting %d.\n",
                        pa->type, ISAKMP_NPTYPE_HASH);
@@ -468,9 +467,15 @@ quick_i2recv(iph2, msg0)
        /* allocate buffer for computing HASH(2) */
        tlen = iph2->nonce->l
                + ntohl(isakmp->len) - sizeof(*isakmp);
+       if (tlen < 0) {
+               plog(ASL_LEVEL_ERR, 
+                        "invalid length (%lu,%d) while getting hash buffer.\n",
+                        iph2->nonce->l, ntohl(isakmp->len));
+               goto end;
+       }
        hbuf = vmalloc(tlen);
        if (hbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get hash buffer.\n");
                goto end;
        }
@@ -492,13 +497,13 @@ quick_i2recv(iph2, msg0)
                switch (pa->type) {
                case ISAKMP_NPTYPE_SA:
                        if (iph2->sa_ret != NULL) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                        "Ignored, multiple SA "
                                        "isn't supported.\n");
                                break;
                        }
                        if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                         "failed to process SA payload");
                                goto end;
                        }
@@ -506,7 +511,7 @@ quick_i2recv(iph2, msg0)
 
                case ISAKMP_NPTYPE_NONCE:
                        if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                         "failed to process NONCE payload");
                                goto end;
                        }
@@ -514,7 +519,7 @@ quick_i2recv(iph2, msg0)
 
                case ISAKMP_NPTYPE_KE:
                        if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                         "failed to process KE payload");
                                goto end;
                        }
@@ -524,6 +529,11 @@ quick_i2recv(iph2, msg0)
                    {
                                vchar_t *vp;
 
+                if (iph2->id == NULL || iph2->id_p == NULL) {
+                    error = ISAKMP_INTERNAL_ERROR;  // shouldn't happen
+                    goto end;
+                }
+                
                                /* check ID value */
                                if (f_id == 0) {
                                        /* for IDci */
@@ -537,7 +547,7 @@ quick_i2recv(iph2, msg0)
                                 * RFC 2407 says that the protocol and port fields should be ignored
                                 * if they are zero, therefore they need to be checked individually.
                                 */
-                               struct ipsecdoi_id_b *id_ptr = (struct ipsecdoi_id_b *)vp->v;
+                               struct ipsecdoi_id_b *id_ptr = ALIGNED_CAST(struct ipsecdoi_id_b *)vp->v;
                                struct ipsecdoi_pl_id *idp_ptr = (struct ipsecdoi_pl_id *)pa->ptr;
                                
                                if (id_ptr->type != idp_ptr->b.type
@@ -547,7 +557,7 @@ quick_i2recv(iph2, msg0)
                                                        vp->l - sizeof(struct ipsecdoi_id_b))) {
                                        // to support servers that use our external nat address as our ID
                                        if (iph2->ph1->natt_flags & NAT_DETECTED) {
-                                               plog(LLV_WARNING, LOCATION, NULL,
+                                               plog(ASL_LEVEL_WARNING, 
                                                        "mismatched ID was returned - ignored because nat traversal is being used.\n");
                                                /* If I'm behind a nat and the ID is type address - save the address
                                                 * and port for when the peer rekeys.
@@ -555,9 +565,13 @@ quick_i2recv(iph2, msg0)
                                                if (f_id == 0 && (iph2->ph1->natt_flags & NAT_DETECTED_ME)) {
                                                        if (lcconf->ext_nat_id)
                                                                vfree(lcconf->ext_nat_id);
+                                                       if (idp_ptr->h.len < sizeof(struct isakmp_gen)) {
+                                                               plog(ASL_LEVEL_ERR, "invalid length (%d) while allocating external nat id.\n", idp_ptr->h.len);
+                                                               goto end;
+                                                       }
                                                        lcconf->ext_nat_id = vmalloc(ntohs(idp_ptr->h.len) - sizeof(struct isakmp_gen));
                                                        if (lcconf->ext_nat_id == NULL) {
-                                                               plog(LLV_ERROR, LOCATION, NULL, "memory error while allocating external nat id.\n");
+                                                               plog(ASL_LEVEL_ERR, "memory error while allocating external nat id.\n");
                                                                goto end;
                                                        }
                                                        memcpy(lcconf->ext_nat_id->v, &(idp_ptr->b), lcconf->ext_nat_id->l);
@@ -565,25 +579,23 @@ quick_i2recv(iph2, msg0)
                                                                vfree(iph2->ext_nat_id);
                                                        iph2->ext_nat_id = vdup(lcconf->ext_nat_id);
                                                        if (iph2->ext_nat_id == NULL) {
-                                                               plog(LLV_ERROR, LOCATION, NULL, "memory error while allocating ph2's external nat id.\n");
+                                                               plog(ASL_LEVEL_ERR, "memory error while allocating ph2's external nat id.\n");
                                                                goto end;
                                                        }
-                                                       plog(LLV_DEBUG, LOCATION, NULL, "external nat address saved.\n");
-                                                       plogdump(LLV_DEBUG, iph2->ext_nat_id->v, iph2->ext_nat_id->l);
+                                                       plogdump(ASL_LEVEL_DEBUG, iph2->ext_nat_id->v, iph2->ext_nat_id->l, "external nat address saved.\n");
                                                } else if (f_id && (iph2->ph1->natt_flags & NAT_DETECTED_PEER)) {
                                                        if (iph2->ext_nat_id_p)
                                                                vfree(iph2->ext_nat_id_p);
                                                        iph2->ext_nat_id_p = vmalloc(ntohs(idp_ptr->h.len) - sizeof(struct isakmp_gen));
                                                        if (iph2->ext_nat_id_p == NULL) {
-                                                               plog(LLV_ERROR, LOCATION, NULL, "memory error while allocating peers ph2's external nat id.\n");
+                                                               plog(ASL_LEVEL_ERR, "memory error while allocating peers ph2's external nat id.\n");
                                                                goto end;
                                                        }
                                                        memcpy(iph2->ext_nat_id_p->v, &(idp_ptr->b), iph2->ext_nat_id_p->l);
-                                                       plog(LLV_DEBUG, LOCATION, NULL, "peer's external nat address saved.\n");
-                                                       plogdump(LLV_DEBUG, iph2->ext_nat_id_p->v, iph2->ext_nat_id_p->l);
+                                                       plogdump(ASL_LEVEL_DEBUG, iph2->ext_nat_id_p->v, iph2->ext_nat_id_p->l, "peer's external nat address saved.\n");
                                                } 
                                        } else {
-                                               plog(LLV_ERROR, LOCATION, NULL, "mismatched ID was returned.\n");
+                                               plog(ASL_LEVEL_ERR, "mismatched ID was returned.\n");
                                                error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
                                                goto end;
                                        }
@@ -603,7 +615,7 @@ quick_i2recv(iph2, msg0)
                case ISAKMP_NPTYPE_NATOA_RFC:
                    {
                                vchar_t         *vp = NULL;
-                               struct sockaddr *daddr;
+                               struct sockaddr_storage *daddr;
 
                                isakmp_p2ph(&vp, pa->ptr);
 
@@ -612,12 +624,12 @@ quick_i2recv(iph2, msg0)
                                        if (daddr) {
                                                if (natoa_i == NULL) {
                                                        natoa_i = daddr;
-                                                       plog(LLV_DEBUG, LOCATION, NULL, "initiaor rcvd NAT-OA i: %s\n",
-                                                                saddr2str(natoa_i));
+                                                       plog(ASL_LEVEL_DEBUG, "initiaor rcvd NAT-OA i: %s\n",
+                                                                saddr2str((struct sockaddr *)natoa_i));
                                                } else if (natoa_r == NULL) {
                                                        natoa_r = daddr;
-                                                       plog(LLV_DEBUG, LOCATION, NULL, "initiator rcvd NAT-OA r: %s\n",
-                                                                saddr2str(natoa_r));
+                                                       plog(ASL_LEVEL_DEBUG, "initiator rcvd NAT-OA r: %s\n",
+                                                                saddr2str((struct sockaddr *)natoa_r));
                                                } else {
                                                        racoon_free(daddr);
                                                }
@@ -631,7 +643,7 @@ quick_i2recv(iph2, msg0)
 
                default:
                        /* don't send information, see ident_r1recv() */
-                       plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+                       plog(ASL_LEVEL_ERR,
                                "ignore the packet, "
                                "received unexpecting payload type %d.\n",
                                pa->type);
@@ -646,14 +658,14 @@ quick_i2recv(iph2, msg0)
 
        /* payload existency check */
        if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "few isakmp message received.\n");
                goto end;
        }
 
        /* Fixed buffer for calculating HASH */
        memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
-       plog(LLV_DEBUG, LOCATION, NULL,
+       plog(ASL_LEVEL_DEBUG, 
                "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
                hbuf->l, tlen + iph2->nonce->l);
        /* adjust buffer length for HASH */
@@ -667,21 +679,20 @@ quick_i2recv(iph2, msg0)
 
        r_hash = (char *)hash + sizeof(*hash);
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH(2) received:");
-       plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
+       //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(2) received:");
 
        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
        if (my_hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to compute HASH");
                goto end;
        }
 
-       result = memcmp(my_hash->v, r_hash, my_hash->l);
+       result = timingsafe_bcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
 
        if (result) {
-               plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_DEBUG,
                        "HASH(2) mismatch.\n");
                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
                goto end;
@@ -690,14 +701,14 @@ quick_i2recv(iph2, msg0)
 
        /* validity check SA payload sent from responder */
        if (ipsecdoi_checkph2proposal(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to validate SA proposal");
                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
                goto end;
        }
 
        /* change status of isakmp status entry */
-       iph2->status = PHASE2ST_STATUS6;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_MSG2RCVD);
 
        error = 0;
 
@@ -728,13 +739,10 @@ end:
                racoon_free(natoa_r);
        }
 #endif
-
        if (error) {
                VPTRINIT(iph2->sa_ret);
                VPTRINIT(iph2->nonce_p);
                VPTRINIT(iph2->dhpub_p);
-               VPTRINIT(iph2->id);
-               VPTRINIT(iph2->id_p);
        }
 
        return error;
@@ -745,8 +753,8 @@ end:
  *     HDR*, HASH(3)
  */
 int
-quick_i2send(iph2, msg0)
-       struct ph2handle *iph2;
+quick_i3send(iph2, msg0)
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
@@ -758,8 +766,8 @@ quick_i2send(iph2, msg0)
        int packet_error = -1;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_STATUS6) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_I_MSG2RCVD) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
@@ -768,11 +776,11 @@ quick_i2send(iph2, msg0)
     {
        vchar_t *tmp = NULL;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) generate\n");
+       plog(ASL_LEVEL_DEBUG, "HASH(3) generate\n");
 
        tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l);
        if (tmp == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get hash buffer.\n");
                goto end;
        }
@@ -783,7 +791,7 @@ quick_i2send(iph2, msg0)
        vfree(tmp);
 
        if (hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to compute HASH");
                goto end;
        }
@@ -794,7 +802,7 @@ quick_i2send(iph2, msg0)
                + sizeof(struct isakmp_gen) + hash->l;
        buf = vmalloc(tlen);
        if (buf == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get buffer to send.\n");
                goto end;
        }
@@ -802,7 +810,7 @@ quick_i2send(iph2, msg0)
        /* create isakmp header */
        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
        if (p == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to create ISAKMP header");
                goto end;
        }
@@ -817,7 +825,7 @@ quick_i2send(iph2, msg0)
        /* encoding */
        iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
        if (iph2->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to encrypt packet");
                goto end;
        }
@@ -827,24 +835,24 @@ quick_i2send(iph2, msg0)
                /* send the packet, add to the schedule to resend */
                iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
                if (isakmp_ph2resend(iph2) == -1) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "failed to send packet, commit-bit");
                        goto end;
                }
        } else {
                /* send the packet */
                if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "failed to send packet");
                        goto end;
                }
        }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
+       if (ike_session_add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
                      iph2->sendbuf, msg0,
-                     PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
-               plog(LLV_ERROR , LOCATION, NULL,
+                     PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH2_FRAG_FLAGS(iph2)) == -1) {
+               plog(ASL_LEVEL_ERR , 
                        "failed to add a response packet to the tree.\n");
                goto end;
        }
@@ -857,40 +865,34 @@ quick_i2send(iph2, msg0)
 
        /* compute both of KEYMATs */
        if (oakley_compute_keymat(iph2, INITIATOR) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to compute KEYMAT");
                goto end;
        }
 
-       iph2->status = PHASE2ST_ADDSA;
-
-       /* don't anything if local test mode. */
-       if (f_local) {
-               error = 0;
-               goto end;
-       }
-
        /* if there is commit bit don't set up SA now. */
        if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
-               iph2->status = PHASE2ST_COMMIT;
+        fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_MSG3SENT);
                error = 0;
                goto end;
        }
+       
+    fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_ADDSA);
 
        /* Do UPDATE for initiator */
-       plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
+       plog(ASL_LEVEL_DEBUG, "call pk_sendupdate\n");
        if (pk_sendupdate(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
+               plog(ASL_LEVEL_ERR, "pfkey update failed.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey update sent.\n");
 
        /* Do ADD for responder */
        if (pk_sendadd(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
+               plog(ASL_LEVEL_ERR, "pfkey add failed.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey add sent.\n");
 
        error = 0;
 
@@ -916,8 +918,8 @@ end:
  *     HDR#*, HASH(4), notify
  */
 int
-quick_i3recv(iph2, msg0)
-       struct ph2handle *iph2;
+quick_i4recv(iph2, msg0)
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
@@ -929,34 +931,34 @@ quick_i3recv(iph2, msg0)
        int packet_error = -1;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_COMMIT) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_I_MSG3SENT) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* decrypt packet */
        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "Packet wasn't encrypted.\n");
                goto end;
        }
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
        if (msg == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to decrypt packet");
+               plog(ASL_LEVEL_ERR,
+                        "failed to decrypt packet\n");
                goto end;
        }
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
        if (pbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to parse msg");
+               plog(ASL_LEVEL_ERR,
+                        "failed to parse msg\n");
                goto end;
        }
 
-       for (pa = (struct isakmp_parse_t *)pbuf->v;
+       for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
             pa++) {
 
@@ -966,14 +968,14 @@ quick_i3recv(iph2, msg0)
                        break;
                case ISAKMP_NPTYPE_N:
                        if (notify != NULL) {
-                               plog(LLV_WARNING, LOCATION, NULL,
+                               plog(ASL_LEVEL_WARNING,
                                    "Ignoring multiple notifications\n");
                                break;
                        }
                        isakmp_check_ph2_notify(pa->ptr, iph2);
                        notify = vmalloc(pa->len);
                        if (notify == NULL) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR,
                                        "failed to get notify buffer.\n");
                                goto end;
                        }
@@ -981,7 +983,7 @@ quick_i3recv(iph2, msg0)
                        break;
                default:
                        /* don't send information, see ident_r1recv() */
-                       plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+                       plog(ASL_LEVEL_ERR,
                                "ignore the packet, "
                                "received unexpecting payload type %d.\n",
                                pa->type);
@@ -991,7 +993,7 @@ quick_i3recv(iph2, msg0)
 
        /* payload existency check */
        if (hash == NULL) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "few isakmp message received.\n");
                goto end;
        }
@@ -1005,22 +1007,21 @@ quick_i3recv(iph2, msg0)
 
        r_hash = (char *)hash + sizeof(*hash);
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) validate:");
-       plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
+       //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(4) validate:");
 
        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
        vfree(tmp);
        if (my_hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to compute HASH");
+               plog(ASL_LEVEL_ERR,
+                        "failed to compute HASH\n");
                goto end;
        }
 
-       result = memcmp(my_hash->v, r_hash, my_hash->l);
+       result = timingsafe_bcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
 
        if (result) {
-               plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_DEBUG,
                        "HASH(4) mismatch.\n");
                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
                goto end;
@@ -1033,7 +1034,8 @@ quick_i3recv(iph2, msg0)
                                                        CONSTSTR(NULL));
        packet_error = 0;
 
-       iph2->status = PHASE2ST_ADDSA;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_ADDSA);
+    
        iph2->flags ^= ISAKMP_FLAG_C;   /* reset bit */
 
        /* don't anything if local test mode. */
@@ -1043,19 +1045,19 @@ quick_i3recv(iph2, msg0)
        }
 
        /* Do UPDATE for initiator */
-       plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
+       plog(ASL_LEVEL_DEBUG, "call pk_sendupdate\n");
        if (pk_sendupdate(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
+               plog(ASL_LEVEL_ERR, "pfkey update failed.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey update sent.\n");
 
        /* Do ADD for responder */
        if (pk_sendadd(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
+               plog(ASL_LEVEL_ERR, "pfkey add failed.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey add sent.\n");
 
        error = 0;
 
@@ -1082,7 +1084,7 @@ end:
  */
 int
 quick_r1recv(iph2, msg0)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
@@ -1095,19 +1097,19 @@ quick_r1recv(iph2, msg0)
        int tlen;
        int f_id_order; /* for ID payload detection */
        int error = ISAKMP_INTERNAL_ERROR;
-       struct sockaddr *natoa_i = NULL;
-       struct sockaddr *natoa_r = NULL;
+       struct sockaddr_storage *natoa_i = NULL;
+       struct sockaddr_storage *natoa_r = NULL;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_START) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_R_START) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* decrypting */
        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "Packet wasn't encrypted.\n");
                error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
                goto end;
@@ -1115,8 +1117,8 @@ quick_r1recv(iph2, msg0)
        /* decrypt packet */
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
        if (msg == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to decrypt packet");
+               plog(ASL_LEVEL_ERR,
+                        "failed to decrypt packet\n");
                goto end;
        }
 
@@ -1129,15 +1131,15 @@ quick_r1recv(iph2, msg0)
         */
        pbuf = isakmp_parse(msg);
        if (pbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to parse msg");
+               plog(ASL_LEVEL_ERR,
+                        "failed to parse msg\n");
                goto end;
        }
-       pa = (struct isakmp_parse_t *)pbuf->v;
+       pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
 
        /* HASH payload is fixed postion */
        if (pa->type != ISAKMP_NPTYPE_HASH) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "received invalid next payload type %d, "
                        "expecting %d.\n",
                        pa->type, ISAKMP_NPTYPE_HASH);
@@ -1154,7 +1156,7 @@ quick_r1recv(iph2, msg0)
         */
        /* HASH payload is fixed postion */
        if (pa->type != ISAKMP_NPTYPE_SA) {
-               plog(LLV_WARNING, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_WARNING,
                        "received invalid next payload type %d, "
                        "expecting %d.\n",
                        pa->type, ISAKMP_NPTYPE_SA);
@@ -1163,9 +1165,14 @@ quick_r1recv(iph2, msg0)
 
        /* allocate buffer for computing HASH(1) */
        tlen = ntohl(isakmp->len) - sizeof(*isakmp);
+       if (tlen < 0) {
+               plog(ASL_LEVEL_ERR, "invalid length (%d) while extracting hash.\n",
+                        ntohl(isakmp->len));
+               goto end;
+       }
        hbuf = vmalloc(tlen);
        if (hbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get hash buffer.\n");
                goto end;
        }
@@ -1201,29 +1208,29 @@ quick_r1recv(iph2, msg0)
                switch (pa->type) {
                case ISAKMP_NPTYPE_SA:
                        if (iph2->sa != NULL) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR,
                                        "Multi SAs isn't supported.\n");
                                goto end;
                        }
                        if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
-                                        "failed to process SA payload");
+                               plog(ASL_LEVEL_ERR,
+                                        "failed to process SA payload\n");
                                goto end;
                        }
                        break;
 
                case ISAKMP_NPTYPE_NONCE:
                        if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
-                                        "failed to process NONCE payload");
+                               plog(ASL_LEVEL_ERR,
+                                        "failed to process NONCE payload\n");
                                goto end;
                        }
                        break;
 
                case ISAKMP_NPTYPE_KE:
                        if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
-                                        "failed to process KE payload");
+                               plog(ASL_LEVEL_ERR,
+                                        "failed to process KE payload\n");
                                goto end;
                        }
                        break;
@@ -1234,15 +1241,15 @@ quick_r1recv(iph2, msg0)
                                f_id_order++;
 
                                if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) {
-                                       plog(LLV_ERROR, LOCATION, NULL,
-                                                "failed to process IDci2 payload");
+                                       plog(ASL_LEVEL_ERR,
+                                                "failed to process IDci2 payload\n");
                                        goto end;
                                }
 
                        } else if (iph2->id == NULL) {
                                /* for IDcr */
                                if (f_id_order == 0) {
-                                       plog(LLV_ERROR, LOCATION, NULL,
+                                       plog(ASL_LEVEL_ERR,
                                                "IDr2 payload is not "
                                                "immediatelly followed "
                                                "by IDi2. We allowed.\n");
@@ -1250,14 +1257,12 @@ quick_r1recv(iph2, msg0)
                                }
 
                                if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) {
-                                       plog(LLV_ERROR, LOCATION, NULL,
-                                                "failed to process IDcr2 payload");
+                                       plog(ASL_LEVEL_ERR,
+                                                "failed to process IDcr2 payload\n");
                                        goto end;
                                }
                        } else {
-                               plog(LLV_ERROR, LOCATION, NULL,
-                                       "received too many ID payloads.\n");
-                               plogdump(LLV_ERROR, iph2->id->v, iph2->id->l);
+                               plogdump(ASL_LEVEL_ERR, iph2->id->v, iph2->id->l, "received too many ID payloads");
                                error = ISAKMP_NTYPE_INVALID_ID_INFORMATION;
                                goto end;
                        }
@@ -1273,7 +1278,7 @@ quick_r1recv(iph2, msg0)
                case ISAKMP_NPTYPE_NATOA_RFC:
                    {
                                vchar_t         *vp = NULL;
-                               struct sockaddr *daddr;
+                               struct sockaddr_storage *daddr;
                                
                                isakmp_p2ph(&vp, pa->ptr);
                                
@@ -1282,12 +1287,12 @@ quick_r1recv(iph2, msg0)
                                        if (daddr) {
                                                if (natoa_i == NULL) {
                                                        natoa_i = daddr;
-                                                       plog(LLV_DEBUG, LOCATION, NULL, "responder rcvd NAT-OA i: %s\n",
-                                                                saddr2str(natoa_i));
+                                                       plog(ASL_LEVEL_DEBUG, "responder rcvd NAT-OA i: %s\n",
+                                                                saddr2str((struct sockaddr *)natoa_i));
                                                } else if (natoa_r == NULL) {
                                                        natoa_r = daddr;
-                                                       plog(LLV_DEBUG, LOCATION, NULL, "responder rcvd NAT-OA r: %s\n",
-                                                                saddr2str(natoa_r));
+                                                       plog(ASL_LEVEL_DEBUG, "responder rcvd NAT-OA r: %s\n",
+                                                                saddr2str((struct sockaddr *)natoa_r));
                                                } else {
                                                        racoon_free(daddr);
                                                }
@@ -1300,7 +1305,7 @@ quick_r1recv(iph2, msg0)
 #endif
 
                default:
-                       plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+                       plog(ASL_LEVEL_ERR,
                                "ignore the packet, "
                                "received unexpected payload type %d.\n",
                                pa->type);
@@ -1316,19 +1321,17 @@ quick_r1recv(iph2, msg0)
 
        /* payload existency check */
        if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "expected isakmp payloads missing.\n");
                error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
                goto end;
        }
 
        if (iph2->id_p) {
-               plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:");
-               plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
+               plogdump(ASL_LEVEL_DEBUG, iph2->id_p->v, iph2->id_p->l, "received IDci2:");
        }
        if (iph2->id) {
-               plog(LLV_DEBUG, LOCATION, NULL, "received IDcr2:");
-               plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
+               plogdump(ASL_LEVEL_DEBUG, iph2->id->v, iph2->id->l, "received IDcr2:");
        }
 
        /* adjust buffer length for HASH */
@@ -1342,21 +1345,20 @@ quick_r1recv(iph2, msg0)
 
        r_hash = (caddr_t)hash + sizeof(*hash);
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH(1) validate:");
-       plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
+       //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(1) validate:");
 
        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
        if (my_hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to compute HASH");
+               plog(ASL_LEVEL_ERR,
+                        "failed to compute HASH\n");
                goto end;
        }
 
-       result = memcmp(my_hash->v, r_hash, my_hash->l);
+       result = timingsafe_bcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
 
        if (result) {
-               plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "HASH(1) mismatch.\n");
                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
                goto end;
@@ -1366,7 +1368,7 @@ quick_r1recv(iph2, msg0)
        /* get sainfo */
        error = get_sainfo_r(iph2);
        if (error) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get sainfo.\n");
                goto end;
        }
@@ -1377,36 +1379,37 @@ quick_r1recv(iph2, msg0)
        case -2:
                /* generate a policy template from peer's proposal */
                if (set_proposal_from_proposal(iph2)) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                "failed to generate a proposal template "
                                "from client's proposal.\n");
-                       return ISAKMP_INTERNAL_ERROR;
+                       error = ISAKMP_INTERNAL_ERROR;
+                       goto end;
                }
                /*FALLTHROUGH*/
        case 0:
                /* select single proposal or reject it. */
                if (ipsecdoi_selectph2proposal(iph2) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to select proposal.\n");
                        error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
                        goto end;
                }
                break;
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get proposal for responder.\n");
                goto end;
        }
 
        /* check KE and attribute of PFS */
        if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "no PFS is specified, but peer sends KE.\n");
                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
                goto end;
        }
        if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "PFS is specified, but peer doesn't sends KE.\n");
                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
                goto end;
@@ -1421,7 +1424,7 @@ quick_r1recv(iph2, msg0)
        iph2->msg1 = vdup(msg0);
 
        /* change status of isakmp status entry */
-       iph2->status = PHASE2ST_STATUS2;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_MSG1RCVD);
 
        error = 0;
 
@@ -1468,29 +1471,29 @@ end:
  * call pfkey_getspi.
  */
 int
-quick_r1prep(iph2, msg)
-       struct ph2handle *iph2;
+quick_rprep(iph2, msg)
+       phase2_handle_t *iph2;
        vchar_t *msg;
 {
        int error = ISAKMP_INTERNAL_ERROR;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_STATUS2) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_R_MSG1RCVD) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
-       iph2->status = PHASE2ST_GETSPISENT;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_GETSPISENT);
 
        /* send getspi message */
        if (pk_sendgetspi(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to send getspi");
                goto end;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey getspi sent.\n");
 
        iph2->sce = sched_new(lcconf->wait_ph2complete,
                pfkey_timeover_stub, iph2);
@@ -1507,7 +1510,7 @@ end:
  */
 int
 quick_r2send(iph2, msg)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        vchar_t *msg;
 {
        vchar_t *body = NULL;
@@ -1524,26 +1527,26 @@ quick_r2send(iph2, msg)
 
        /* validity check */
        if (msg != NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "msg has to be NULL in this function.\n");
                goto end;
        }
-       if (iph2->status != PHASE2ST_GETSPIDONE) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_R_GETSPIDONE) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* update responders SPI */
        if (ipsecdoi_updatespi(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "failed to update spi.\n");
+               plog(ASL_LEVEL_ERR, "failed to update spi.\n");
                goto end;
        }
 
        /* generate NONCE value */
        iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
        if (iph2->nonce == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to generate NONCE");
                goto end;
        }
@@ -1553,14 +1556,19 @@ quick_r2send(iph2, msg)
        if (iph2->dhpub_p != NULL && pfsgroup != 0) {
                /* DH group settting if PFS is required. */
                if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                "failed to set DH value.\n");
                        goto end;
                }
                /* generate DH public value */
+#ifdef HAVE_OPENSSL
                if (oakley_dh_generate(iph2->pfsgrp,
                                &iph2->dhpub, &iph2->dhpriv) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+#else
+                       if (oakley_dh_generate(iph2->pfsgrp,
+                                                                  &iph2->dhpub, &iph2->publicKeySize, &iph2->dhC) < 0) {
+#endif         
+                       plog(ASL_LEVEL_ERR,
                                 "failed to generate DH public");
                        goto end;
                }
@@ -1584,7 +1592,7 @@ quick_r2send(iph2, msg)
                && (iph2->ph1->natt_flags & NAT_DETECTED)) {
                natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r);
                if (natoa_type == -1) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to create NATOA payloads");
                        goto end;
                }
@@ -1592,20 +1600,18 @@ quick_r2send(iph2, msg)
                        tlen += sizeof(*gen) + natoa_i->l;
                        tlen += sizeof(*gen) + natoa_r->l;
                        
-                       plog(LLV_DEBUG, LOCATION, NULL, "responder send NAT-OAi:\n");
-                       plogdump(LLV_DEBUG, natoa_i->v, natoa_i->l);
-                       plog(LLV_DEBUG, LOCATION, NULL, "responder send NAT-OAr:\n");
-                       plogdump(LLV_DEBUG, natoa_r->v, natoa_r->l);
+                       //plogdump(ASL_LEVEL_DEBUG, natoa_i->v, natoa_i->l, "responder send NAT-OAi:");
+                       //plogdump(ASL_LEVEL_DEBUG, natoa_r->v, natoa_r->l, "responder send NAT-OAr:");
                }
        }
 #endif
 
-       plog(LLV_DEBUG, LOCATION, NULL, "Approved SA\n");
-       printsaprop0(LLV_DEBUG, iph2->approval);
+       plog(ASL_LEVEL_DEBUG, "Approved SA\n");
+       printsaprop0(ASL_LEVEL_DEBUG, iph2->approval);
 
        body = vmalloc(tlen);
        if (body == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get buffer to send.\n");
                goto end;
        }
@@ -1634,13 +1640,11 @@ quick_r2send(iph2, msg)
        if (iph2->id_p != NULL) {
                /* IDci */
                p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
-               plog(LLV_DEBUG, LOCATION, NULL, "sending IDci2:\n");
-               plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
+               plogdump(ASL_LEVEL_DEBUG, iph2->id_p->v, iph2->id_p->l, "sending IDci2:");
                /* IDcr */
                np_p = &((struct isakmp_gen *)p)->np;   /* XXX */
                p = set_isakmp_payload(p, iph2->id, (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE));
-               plog(LLV_DEBUG, LOCATION, NULL, "sending IDcr2:\n");
-               plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
+               plogdump(ASL_LEVEL_DEBUG, iph2->id->v, iph2->id->l, "sending IDcr2:");
        }
 
        /* add a RESPONDER-LIFETIME notify payload if needed */
@@ -1654,14 +1658,14 @@ quick_r2send(iph2, msg)
                data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
                                        IPSECDOI_ATTR_SA_LD_TYPE_SEC);
                if (!data) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to add RESPONDER-LIFETIME notify (type) payload");
                        goto end;
                }
                data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
                                        (caddr_t)&v, sizeof(v));
                if (!data) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to add RESPONDER-LIFETIME notify (value) payload");
                        goto end;
                }
@@ -1671,14 +1675,14 @@ quick_r2send(iph2, msg)
                data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
                                        IPSECDOI_ATTR_SA_LD_TYPE_KB);
                if (!data) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to add RESPONDER-LIFETIME notify (type) payload");
                        goto end;
                }
                data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
                                        (caddr_t)&v, sizeof(v));
                if (!data) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                 "failed to add RESPONDER-LIFETIME notify (value) payload");
                        goto end;
                }
@@ -1693,7 +1697,7 @@ quick_r2send(iph2, msg)
                        body = isakmp_add_pl_n(body, &np_p,
                                        ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
                        if (!body) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR,
                                         "invalid RESPONDER-LIFETIME payload");
                                vfree(data);
                                return error;   /* XXX */
@@ -1715,7 +1719,7 @@ quick_r2send(iph2, msg)
 
        tmp = vmalloc(iph2->nonce_p->l + body->l);
        if (tmp == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get hash buffer.\n");
                goto end;
        }
@@ -1726,7 +1730,7 @@ quick_r2send(iph2, msg)
        vfree(tmp);
 
        if (hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to compute HASH");
                goto end;
     }
@@ -1735,7 +1739,7 @@ quick_r2send(iph2, msg)
        /* send isakmp payload */
        iph2->sendbuf = quick_ir1mx(iph2, body, hash);
        if (iph2->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to get send buffer");
                goto end;
        }
@@ -1743,21 +1747,21 @@ quick_r2send(iph2, msg)
        /* send the packet, add to the schedule to resend */
        iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
        if (isakmp_ph2resend(iph2) == -1) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to send packet");
                goto end;
        }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1,
-                     PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
-               plog(LLV_ERROR , LOCATION, NULL,
+       if (ike_session_add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1,
+                     PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH2_FRAG_FLAGS(iph2)) == -1) {
+               plog(ASL_LEVEL_ERR,
                        "failed to add a response packet to the tree.\n");
                goto end;
        }
 
        /* change status of isakmp status entry */
-       iph2->status = PHASE2ST_MSG1SENT;
+    fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_MSG2SENT);
 
        error = 0;
 
@@ -1791,7 +1795,7 @@ end:
  */
 int
 quick_r3recv(iph2, msg0)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
@@ -1801,34 +1805,34 @@ quick_r3recv(iph2, msg0)
        int error = ISAKMP_INTERNAL_ERROR;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_MSG1SENT) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_R_MSG2SENT) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* decrypt packet */
        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "Packet wasn't encrypted.\n");
                goto end;
        }
        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
        if (msg == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to decrypt packet");
+               plog(ASL_LEVEL_ERR,
+                        "failed to decrypt packet\n");
                goto end;
        }
 
        /* validate the type of next payload */
        pbuf = isakmp_parse(msg);
        if (pbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to parse msg");
+               plog(ASL_LEVEL_ERR, 
+                        "failed to parse msg\n");
                goto end;
        }
 
-       for (pa = (struct isakmp_parse_t *)pbuf->v;
+       for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
             pa->type != ISAKMP_NPTYPE_NONE;
             pa++) {
 
@@ -1841,7 +1845,7 @@ quick_r3recv(iph2, msg0)
                        break;
                default:
                        /* don't send information, see ident_r1recv() */
-                       plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+                       plog(ASL_LEVEL_ERR,
                                "ignore the packet, "
                                "received unexpecting payload type %d.\n",
                                pa->type);
@@ -1851,7 +1855,7 @@ quick_r3recv(iph2, msg0)
 
        /* payload existency check */
        if (hash == NULL) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "few isakmp message received.\n");
                goto end;
        }
@@ -1866,12 +1870,11 @@ quick_r3recv(iph2, msg0)
 
        r_hash = (char *)hash + sizeof(*hash);
 
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) validate:");
-       plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
+       //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(3) validate:");
 
        tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l);
        if (tmp == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get hash buffer.\n");
                goto end;
        }
@@ -1881,16 +1884,16 @@ quick_r3recv(iph2, msg0)
        my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
        vfree(tmp);
        if (my_hash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to compute HASH");
+               plog(ASL_LEVEL_ERR,
+                        "failed to compute HASH\n");
                goto end;
        }
 
-       result = memcmp(my_hash->v, r_hash, my_hash->l);
+       result = timingsafe_bcmp(my_hash->v, r_hash, my_hash->l);
        vfree(my_hash);
 
        if (result) {
-               plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
+               plog(ASL_LEVEL_ERR,
                        "HASH(3) mismatch.\n");
                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
                goto end;
@@ -1899,9 +1902,9 @@ quick_r3recv(iph2, msg0)
 
        /* if there is commit bit, don't set up SA now. */
        if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
-               iph2->status = PHASE2ST_COMMIT;
+               fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_MSG3RCVD);
        } else
-               iph2->status = PHASE2ST_STATUS6;
+               fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_COMMIT);
 
        error = 0;
 
@@ -1930,8 +1933,8 @@ end:
  *     HDR#*, HASH(4), notify
  */
 int
-quick_r3send(iph2, msg0)
-       struct ph2handle *iph2;
+quick_r4send(iph2, msg0)
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *buf = NULL;
@@ -1943,21 +1946,21 @@ quick_r3send(iph2, msg0)
        int error = ISAKMP_INTERNAL_ERROR;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_COMMIT) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_R_MSG3RCVD) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* generate HASH(4) */
        /* XXX What can I do in the case of multiple different SA */
-       plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) generate\n");
+       plog(ASL_LEVEL_DEBUG, "HASH(4) generate\n");
 
        /* XXX What should I do if there are multiple SAs ? */
        tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize;
        notify = vmalloc(tlen);
        if (notify == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get notify buffer.\n");
                goto end;
        }
@@ -1972,7 +1975,7 @@ quick_r3send(iph2, msg0)
 
        myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
        if (myhash == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to compute HASH");
                goto end;
        }
@@ -1983,7 +1986,7 @@ quick_r3send(iph2, msg0)
                + notify->l;
        buf = vmalloc(tlen);
        if (buf == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                        "failed to get buffer to send.\n");
                goto end;
        }
@@ -1991,7 +1994,7 @@ quick_r3send(iph2, msg0)
        /* create isakmp header */
        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
        if (p == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to set ISAKMP header");
                goto end;
        }
@@ -2009,27 +2012,27 @@ quick_r3send(iph2, msg0)
        /* encoding */
        iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
        if (iph2->sendbuf == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to encrypt packet");
                goto end;
        }
 
        /* send the packet */
        if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to send packet");
                goto end;
        }
 
        /* the sending message is added to the received-list. */
-       if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0,
-                     PH2_NON_ESP_EXTRA_LEN(iph2)) == -1) {
-               plog(LLV_ERROR , LOCATION, NULL,
+       if (ike_session_add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0,
+                     PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH2_FRAG_FLAGS(iph2)) == -1) {
+               plog(ASL_LEVEL_ERR , 
                        "failed to add a response packet to the tree.\n");
                goto end;
        }
 
-       iph2->status = PHASE2ST_COMMIT;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_COMMIT);
 
        error = 0;
 
@@ -2060,28 +2063,29 @@ end:
  * set SA to kernel.
  */
 int
-quick_r3prep(iph2, msg0)
-       struct ph2handle *iph2;
+quick_rfinalize(iph2, msg0)
+       phase2_handle_t *iph2;
        vchar_t *msg0;
 {
        vchar_t *msg = NULL;
        int error = ISAKMP_INTERNAL_ERROR;
 
        /* validity check */
-       if (iph2->status != PHASE2ST_STATUS6) {
-               plog(LLV_ERROR, LOCATION, NULL,
+       if (iph2->status != IKEV1_STATE_QUICK_R_COMMIT) {
+               plog(ASL_LEVEL_ERR,
                        "status mismatched %d.\n", iph2->status);
                goto end;
        }
 
        /* compute both of KEYMATs */
        if (oakley_compute_keymat(iph2, RESPONDER) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR,
                         "failed to compute KEYMAT");
                goto end;
        }
 
-       iph2->status = PHASE2ST_ADDSA;
+       fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_ADDSA);
+    
        iph2->flags ^= ISAKMP_FLAG_C;   /* reset bit */
 
        /* don't anything if local test mode. */
@@ -2091,19 +2095,19 @@ quick_r3prep(iph2, msg0)
        }
 
        /* Do UPDATE as responder */
-       plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
+       plog(ASL_LEVEL_DEBUG, "call pk_sendupdate\n");
        if (pk_sendupdate(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
+               plog(ASL_LEVEL_ERR, "pfkey update failed.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey update sent.\n");
 
        /* Do ADD for responder */
        if (pk_sendadd(iph2) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
+               plog(ASL_LEVEL_ERR, "pfkey add failed.\n");
                goto end;
        }
-       plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
+       plog(ASL_LEVEL_DEBUG, "pfkey add sent.\n");
 
        /*
         * set policies into SPD if the policy is generated
@@ -2114,31 +2118,31 @@ quick_r3prep(iph2, msg0)
                struct policyindex *spidx;
                struct sockaddr_storage addr;
                u_int8_t pref;
-               struct sockaddr *src = iph2->src;
-               struct sockaddr *dst = iph2->dst;
+               struct sockaddr_storage *src = iph2->src;
+               struct sockaddr_storage *dst = iph2->dst;
 
                /* make inbound policy */
                iph2->src = dst;
                iph2->dst = src;
                if (pk_sendspdupdate2(iph2) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                "pfkey spdupdate2(inbound) failed.\n");
                        goto end;
                }
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG,
                        "pfkey spdupdate2(inbound) sent.\n");
 
-               spidx = (struct policyindex *)iph2->spidx_gen;
+               spidx = iph2->spidx_gen;
 #ifdef HAVE_POLICY_FWD
                /* make forward policy if required */
                if (tunnel_mode_prop(iph2->approval)) {
                        spidx->dir = IPSEC_DIR_FWD;
                        if (pk_sendspdupdate2(iph2) < 0) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR,
                                        "pfkey spdupdate2(forward) failed.\n");
                                goto end;
                        }
-                       plog(LLV_DEBUG, LOCATION, NULL,
+                       plog(ASL_LEVEL_DEBUG,
                                "pfkey spdupdate2(forward) sent.\n");
                }
 #endif
@@ -2155,15 +2159,15 @@ quick_r3prep(iph2, msg0)
                spidx->prefd = pref;
 
                if (pk_sendspdupdate2(iph2) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR,
                                "pfkey spdupdate2(outbound) failed.\n");
                        goto end;
                }
-               plog(LLV_DEBUG, LOCATION, NULL,
+               plog(ASL_LEVEL_DEBUG,
                        "pfkey spdupdate2(outbound) sent.\n");
 
                /* spidx_gen is unnecessary any more */
-               delsp_bothdir((struct policyindex *)iph2->spidx_gen);
+               delsp_bothdir(iph2->spidx_gen);
                racoon_free(iph2->spidx_gen);
                iph2->spidx_gen = NULL;
                iph2->generated_spidx=1;
@@ -2183,7 +2187,7 @@ end:
  */
 static vchar_t *
 quick_ir1mx(iph2, body, hash)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        vchar_t *body, *hash;
 {
        struct isakmp *isakmp;
@@ -2199,7 +2203,7 @@ quick_ir1mx(iph2, body, hash)
                + body->l;
        buf = vmalloc(tlen);
        if (buf == NULL) { 
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to get buffer to send.\n");
                goto end;
        }
@@ -2210,7 +2214,7 @@ quick_ir1mx(iph2, body, hash)
        /* set isakmp header */
        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
        if (p == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to set ISAKMP header");
                goto end;
        }
@@ -2229,7 +2233,7 @@ quick_ir1mx(iph2, body, hash)
        /* encoding */
        new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
        if (new == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                         "failed to encrypt packet");
                goto end;
        }
@@ -2253,9 +2257,9 @@ end:
  * get remote's sainfo.
  * NOTE: this function is for responder.
  */
-static int
+int
 get_sainfo_r(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        vchar_t *idsrc = NULL, *iddst = NULL;
        int prefixlen;
@@ -2263,7 +2267,7 @@ get_sainfo_r(iph2)
        struct sainfo *anonymous = NULL;
 
        if (iph2->id == NULL) {
-               switch (iph2->src->sa_family) {
+               switch (iph2->src->ss_family) {
                case AF_INET:
                        prefixlen = sizeof(struct in_addr) << 3;
                        break;
@@ -2271,8 +2275,8 @@ get_sainfo_r(iph2)
                        prefixlen = sizeof(struct in6_addr) << 3;
                        break;
                default:
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "invalid family: %d\n", iph2->src->sa_family);
+                       plog(ASL_LEVEL_ERR, 
+                               "invalid family: %d\n", iph2->src->ss_family);
                        goto end;
                }
                idsrc = ipsecdoi_sockaddr2id(iph2->src, prefixlen,
@@ -2281,13 +2285,13 @@ get_sainfo_r(iph2)
                idsrc = vdup(iph2->id);
        }
        if (idsrc == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to set ID for source.\n");
                goto end;
        }
 
        if (iph2->id_p == NULL) {
-               switch (iph2->dst->sa_family) {
+               switch (iph2->dst->ss_family) {
                case AF_INET:
                        prefixlen = sizeof(struct in_addr) << 3;
                        break;
@@ -2295,8 +2299,8 @@ get_sainfo_r(iph2)
                        prefixlen = sizeof(struct in6_addr) << 3;
                        break;
                default:
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "invalid family: %d\n", iph2->dst->sa_family);
+                       plog(ASL_LEVEL_ERR, 
+                               "invalid family: %d\n", iph2->dst->ss_family);
                        goto end;
                }
                iddst = ipsecdoi_sockaddr2id(iph2->dst, prefixlen,
@@ -2305,7 +2309,7 @@ get_sainfo_r(iph2)
                iddst = vdup(iph2->id_p);
        }
        if (iddst == NULL) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to set ID for destination.\n");
                goto end;
        }
@@ -2320,7 +2324,7 @@ get_sainfo_r(iph2)
                if ((iph2->ph1->natt_flags & NAT_DETECTED_ME) && lcconf->ext_nat_id != NULL)
                        iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, 1);
                if (iph2->sainfo) {
-                       plog(LLV_DEBUG2, LOCATION, NULL,
+                       plog(ASL_LEVEL_DEBUG, 
                                 "get_sainfo_r case 1.\n");
                }
                // still no sainfo (or anonymous): for client, fallback to sainfo used by a previous established phase2
@@ -2328,16 +2332,16 @@ get_sainfo_r(iph2)
                        (iph2->sainfo->idsrc == NULL && iph2->parent_session && iph2->parent_session->is_client)) {
                        ike_session_get_sainfo_r(iph2);
                        if (iph2->sainfo) {
-                               plog(LLV_DEBUG2, LOCATION, NULL,
+                               plog(ASL_LEVEL_DEBUG, 
                                         "get_sainfo_r case 2.\n");
                        }
                        // still no sainfo (or anonymous): fallback to sainfo picked by dst id
                        if ((iph2->sainfo == NULL || iph2->sainfo->idsrc == NULL) && iph2->id_p) {
-                               plog(LLV_DEBUG2, LOCATION, NULL,
+                               plog(ASL_LEVEL_DEBUG, 
                                         "get_sainfo_r about to try dst id only.\n");
                                iph2->sainfo = getsainfo_by_dst_id(iph2->id_p, iph2->ph1->id_p);
                                if (iph2->sainfo) {
-                                       plog(LLV_DEBUG2, LOCATION, NULL,
+                                       plog(ASL_LEVEL_DEBUG, 
                                                 "get_sainfo_r case 3.\n");
                                        if (iph2->sainfo->idsrc == NULL)
                                                anonymous = iph2->sainfo;
@@ -2347,32 +2351,25 @@ get_sainfo_r(iph2)
        }
        if (iph2->sainfo == NULL) {
                if (anonymous == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "failed to get sainfo.\n");
                        goto end;
                }
                iph2->sainfo = anonymous;
        }
-#ifdef __APPLE__
-       if (link_sainfo_to_ph2(iph2->sainfo) != 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                        "failed to link sainfo\n");
-               iph2->sainfo = NULL;
-               goto end;
-       }
-#endif
-       
+       retain_sainfo(iph2->sainfo);
+    
 #ifdef ENABLE_HYBRID
        /* xauth group inclusion check */
        if (iph2->sainfo->group != NULL)
                if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                 "failed to group check");
                        goto end;
                }
 #endif
 
-       plog(LLV_DEBUG, LOCATION, NULL,
+       plog(ASL_LEVEL_DEBUG, 
                "selected sainfo: %s\n", sainfo2str(iph2->sainfo));
 
        error = 0;
@@ -2385,9 +2382,9 @@ end:
        return error;
 }
 
-static int
+int
 get_proposal_r(iph2)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        int error = get_proposal_r_remote(iph2, 0);
        if (error != -2 && error != 0 && 
@@ -2413,37 +2410,36 @@ get_proposal_r(iph2)
  */
 static int
 get_proposal_r_remote(iph2, ignore_id)
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
        int ignore_id;
 {
        struct policyindex spidx;
        struct secpolicy *sp_in, *sp_out;
        int idi2type = 0;       /* switch whether copy IDs into id[src,dst]. */
        int error = ISAKMP_INTERNAL_ERROR;
-       int generated_policy_exit_early = 1;
+    int generated_policy_exit_early = 0;
 
        /* check the existence of ID payload */
        if ((iph2->id_p != NULL && iph2->id == NULL)
         || (iph2->id_p == NULL && iph2->id != NULL)) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "Both IDs wasn't found in payload.\n");
                return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
        }
 
        /* make sure if id[src,dst] is null (if use_remote_addr == 0). */
        if (!ignore_id && (iph2->src_id || iph2->dst_id)) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "Why do ID[src,dst] exist already.\n");
                return ISAKMP_INTERNAL_ERROR;
        }
 
-       plog(LLV_DEBUG, LOCATION, NULL,
+       plog(ASL_LEVEL_DEBUG, 
                 "%s: ignore_id %x.\n", __FUNCTION__, ignore_id);
 
        memset(&spidx, 0, sizeof(spidx));
 
-#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
-
+#define _XIDT(d) (ALIGNED_CAST(struct ipsecdoi_id_b *)((d)->v))->type
        /* make a spidx; a key to search SPD */
        spidx.dir = IPSEC_DIR_INBOUND;
        spidx.ul_proto = 0;
@@ -2461,9 +2457,8 @@ get_proposal_r_remote(iph2, ignore_id)
          || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
          || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
                /* get a destination address of a policy */
-               error = ipsecdoi_id2sockaddr(iph2->id,
-                               (struct sockaddr *)&spidx.dst,
-                               &spidx.prefd, &spidx.ul_proto);
+               error = ipsecdoi_id2sockaddr(iph2->id, &spidx.dst,
+                               &spidx.prefd, &spidx.ul_proto, iph2->version);
                if (error)
                        return error;
 
@@ -2475,8 +2470,7 @@ get_proposal_r_remote(iph2, ignore_id)
                 * because rcoon is responder.
                 */
                if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
-                       error = setscopeid((struct sockaddr *)&spidx.dst,
-                                           iph2->src);
+                       error = setscopeid(&spidx.dst, iph2->src);
                        if (error)
                                return error;
                }
@@ -2488,9 +2482,9 @@ get_proposal_r_remote(iph2, ignore_id)
 
        } 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");
 
@@ -2499,7 +2493,7 @@ get_proposal_r_remote(iph2, ignore_id)
                 * of the key to search the SPD because the direction of policy
                 * is inbound.
                 */
-               memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
+               memcpy(&spidx.dst, iph2->src, sysdep_sa_len((struct sockaddr *)iph2->src));
                switch (spidx.dst.ss_family) {
                case AF_INET:
                        {
@@ -2527,9 +2521,8 @@ get_proposal_r_remote(iph2, ignore_id)
          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
                /* get a source address of inbound SA */
-               error = ipsecdoi_id2sockaddr(iph2->id_p,
-                               (struct sockaddr *)&spidx.src,
-                               &spidx.prefs, &spidx.ul_proto);
+               error = ipsecdoi_id2sockaddr(iph2->id_p, &spidx.src,
+                               &spidx.prefs, &spidx.ul_proto, iph2->version);
                if (error)
                        return error;
 
@@ -2539,8 +2532,7 @@ get_proposal_r_remote(iph2, ignore_id)
                 * for more detail, see above of this function.
                 */
                if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
-                       error = setscopeid((struct sockaddr *)&spidx.src,
-                                           iph2->dst);
+                       error = setscopeid(&spidx.src, iph2->dst);
                        if (error)
                                return error;
                }
@@ -2549,29 +2541,29 @@ get_proposal_r_remote(iph2, ignore_id)
                /* make id[src,dst] if both ID types are IP address and same */
                if (_XIDT(iph2->id_p) == idi2type
                 && spidx.dst.ss_family == spidx.src.ss_family) {
-                       iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst);
+                       iph2->src_id = dupsaddr(&spidx.dst);
                        if (iph2->src_id  == NULL) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                    "buffer allocation failed.\n");
                                return ISAKMP_INTERNAL_ERROR;
                        }
-                       iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src);
+                       iph2->dst_id = dupsaddr(&spidx.src);
                        if (iph2->dst_id  == NULL) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                    "buffer allocation failed.\n");
                                return ISAKMP_INTERNAL_ERROR;
                        }
                }
 
        } 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");
 
                /* see above comment. */
-               memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
+               memcpy(&spidx.src, iph2->dst, sysdep_sa_len((struct sockaddr *)iph2->dst));
                switch (spidx.src.ss_family) {
                case AF_INET:
                        {
@@ -2593,12 +2585,12 @@ get_proposal_r_remote(iph2, ignore_id)
 
 #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 *)&spidx.src),
                spidx.prefs, 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 *)&spidx.dst),
@@ -2616,24 +2608,24 @@ get_proposal_r_remote(iph2, ignore_id)
        if (sp_in == NULL || sp_in->policy == IPSEC_POLICY_GENERATE) {
                if (iph2->ph1->rmconf->gen_policy) {
                        if (sp_in)
-                                plog(LLV_INFO, LOCATION, NULL,
+                                plog(ASL_LEVEL_NOTICE, 
                                        "Update the generated policy : %s\n",
                                        spidx2str(&spidx));
                        else
-                               plog(LLV_INFO, LOCATION, NULL,
+                               plog(ASL_LEVEL_NOTICE, 
                                        "no policy found, "
                                        "try to generate the policy : %s\n",
                                        spidx2str(&spidx));
-                       iph2->spidx_gen = racoon_malloc(sizeof(spidx));
+                       iph2->spidx_gen = (struct policyindex *)racoon_malloc(sizeof(spidx));
                        if (!iph2->spidx_gen) {
-                               plog(LLV_ERROR, LOCATION, NULL,
+                               plog(ASL_LEVEL_ERR, 
                                        "buffer allocation failed.\n");
                                return ISAKMP_INTERNAL_ERROR;
                        }
                        memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
                        generated_policy_exit_early = 1;        /* special value */
                } else {
-                       plog(LLV_ERROR, LOCATION, NULL,
+                       plog(ASL_LEVEL_ERR, 
                                "no policy found: %s\n", spidx2str(&spidx));
                        return ISAKMP_INTERNAL_ERROR;
                }
@@ -2654,7 +2646,7 @@ get_proposal_r_remote(iph2, ignore_id)
 
        sp_out = getsp_r(&spidx, iph2);
        if (!sp_out) {
-               plog(LLV_WARNING, LOCATION, NULL,
+               plog(ASL_LEVEL_WARNING, 
                        "no outbound policy found: %s\n",
                        spidx2str(&spidx));
        } else {
@@ -2665,7 +2657,7 @@ get_proposal_r_remote(iph2, ignore_id)
        }
     }
 
-       plog(LLV_DEBUG, LOCATION, NULL,
+       plog(ASL_LEVEL_DEBUG, 
                "suitable SP found:%s\n", spidx2str(&spidx));
 
        if (generated_policy_exit_early) {
@@ -2677,7 +2669,7 @@ get_proposal_r_remote(iph2, ignore_id)
         * outbound policy is not checked currently.
         */
        if (sp_in->policy != IPSEC_POLICY_IPSEC) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "policy found, but no IPsec required: %s\n",
                        spidx2str(&spidx));
                return ISAKMP_INTERNAL_ERROR;
@@ -2685,7 +2677,7 @@ get_proposal_r_remote(iph2, ignore_id)
 
        /* set new proposal derived from a policy into the iph2->proposal. */
        if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "failed to create saprop.\n");
                return ISAKMP_INTERNAL_ERROR;
        }