]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/handler.c
ipsec-317.220.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / handler.c
index e2871452dc4001cd31af0c642d76a1b6f2b40117..9bb0d191914d0a5cb4f17e55c384acd73d71d09f 100644 (file)
 #include "debug.h"
 #include "fsm.h"
 
-#ifdef ENABLE_HYBRID
-#include <resolv.h>
-#endif
-
 #include "schedule.h"
 #include "grabmyaddr.h"
 #include "algorithm.h"
@@ -81,7 +77,6 @@
 
 #include "power_mgmt.h"
 
-
 extern LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree;
 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
@@ -242,10 +237,19 @@ sike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage
        phase1_handle_t *p = NULL;
            
     LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
-        if (FSM_STATE_IS_EXPIRED(p->status))
+               if (FSM_STATE_IS_EXPIRED(p->status)) {
             continue;
-        if (cmpsaddrwop(remote, p->remote) == 0)
+               }
+               if (remote->ss_family == AF_INET &&
+                       p->nat64_prefix.length) {
+                       struct in_addr address;
+                       nw_nat64_extract_v4(&p->nat64_prefix, &((struct sockaddr_in6 *)p->remote)->sin6_addr, &address);
+                       if (((struct sockaddr_in *)remote)->sin_addr.s_addr == address.s_addr) {
+                               return p;
+                       }
+               } else if (cmpsaddrwop(remote, p->remote) == 0) {
             return p;
+               }
     }
     
     return NULL;
@@ -311,7 +315,7 @@ ike_session_newph1(unsigned int version)
        iph1->ping_sched = NULL;
 #endif
        iph1->is_dying = 0;
-    plog(ASL_LEVEL_DEBUG, "*** New Phase 1\n");
+    plog(ASL_LEVEL_NOTICE, "New Phase 1\n");
        return iph1;
 }
 
@@ -382,8 +386,6 @@ ike_session_delph1(phase1_handle_t *iph1)
        VPTRINIT(iph1->skeyid_a_p);
        VPTRINIT(iph1->skeyid_e);
     VPTRINIT(iph1->skeyid_e_p);
-    VPTRINIT(iph1->skeyid_p);
-    VPTRINIT(iph1->skeyid_p_p);
        VPTRINIT(iph1->key);
     VPTRINIT(iph1->key_p);
        VPTRINIT(iph1->hash);
@@ -426,7 +428,7 @@ ike_session_flush_all_phase1_for_session(ike_session_t *session, int ignore_esta
                
     LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) {
         if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) {
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "Skipping Phase 1 %s that's asserted...\n",
                  isakmp_pindex(&p->index, 0));
             continue;
@@ -436,13 +438,13 @@ ike_session_flush_all_phase1_for_session(ike_session_t *session, int ignore_esta
         if (FSM_STATE_IS_ESTABLISHED(p->status)) {
             if (ignore_estab_or_assert_handles &&
                 (ike_session_has_negoing_ph2(p->parent_session) || ike_session_has_established_ph2(p->parent_session))) {
-                plog(ASL_LEVEL_DEBUG,
+                plog(ASL_LEVEL_NOTICE,
                      "Skipping Phase 1 %s that's established... because it's needed by children Phase 2s\n",
                      isakmp_pindex(&p->index, 0));
                 continue;
             }
             /* send delete information */
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "Got a Phase 1 %s to flush...\n",
                  isakmp_pindex(&p->index, 0));
             isakmp_info_send_d1(p);
@@ -464,7 +466,7 @@ ike_session_flush_all_phase1(int ignore_estab_or_assert_handles)
     ike_session_t *session = NULL;
     ike_session_t *next_session = NULL;
        
-       plog(ASL_LEVEL_DEBUG,
+       plog(ASL_LEVEL_NOTICE,
                 "Flushing Phase 1 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
     
     LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
@@ -526,7 +528,7 @@ ike_session_getph2bymsgid(phase1_handle_t *iph1, u_int32_t msgid)
        phase2_handle_t *p;
     
        LIST_FOREACH(p, &iph1->parent_session->ph2tree, ph2ofsession_chain) {
-               if (p->msgid == msgid)
+               if (p->msgid == msgid && !p->is_defunct)
                        return p;
        }
     
@@ -569,7 +571,7 @@ ike_session_getph2byid(struct sockaddr_storage *src, struct sockaddr_storage *ds
                    p->retry_counter == 0
                    && p->sce == 0 && p->scr == 0 &&
                    p->retry_checkph1 == 0){
-                    plog(ASL_LEVEL_DEBUG,
+                    plog(ASL_LEVEL_NOTICE,
                          "Zombie ph2 found, expiring it\n");
                     isakmp_ph2expire(p);
                 }else
@@ -695,7 +697,7 @@ ike_session_newph2(unsigned int version, int type)
     iph2->phase2_type = type;
        iph2->is_dying = 0;
     
-    plog(ASL_LEVEL_DEBUG, "*** New Phase 2\n");
+    plog(ASL_LEVEL_NOTICE, "New Phase 2\n");
        return iph2;
 }
 
@@ -800,7 +802,6 @@ ike_session_delph2(phase2_handle_t *iph2)
     if (iph2->scr)
         SCHED_KILL(iph2->scr);
     
-    
        racoon_free(iph2);
 }
 
@@ -814,22 +815,22 @@ ike_session_flush_all_phase2_for_session(ike_session_t *session, int ignore_esta
             continue;
         }
         if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) {
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "skipping phase2 handle that's asserted...\n");
             continue;
         }
         if (FSM_STATE_IS_ESTABLISHED(p->status)){
             if (ignore_estab_or_assert_handles) {
-                plog(ASL_LEVEL_DEBUG,
+                plog(ASL_LEVEL_NOTICE,
                      "skipping ph2 handler that's established...\n");
                 continue;
             }
             /* send delete information */
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "got an established ph2 handler to flush...\n");
             isakmp_info_send_d2(p);
         }else{
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "got a ph2 handler to flush (state %d)\n", p->status);
         }
         
@@ -846,7 +847,7 @@ ike_session_flush_all_phase2(int ignore_estab_or_assert_handles)
     ike_session_t *session = NULL;
     ike_session_t *next_session = NULL;
     
-       plog(ASL_LEVEL_DEBUG,
+       plog(ASL_LEVEL_NOTICE,
                 "flushing ph2 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
     
     LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
@@ -895,7 +896,7 @@ ike_session_deleteallph2(struct sockaddr_storage *src, struct sockaddr_storage *
             }
             continue;
         zap_it:
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "deleteallph2: got a ph2 handler...\n");
             if (FSM_STATE_IS_ESTABLISHED(iph2->status))
                 isakmp_info_send_d2(iph2);
@@ -923,7 +924,7 @@ ike_session_deleteallph1(struct sockaddr_storage *src, struct sockaddr_storage *
                 cmpsaddrwop(dst, iph1->remote) != 0) {
                 continue;
             }
-            plog(ASL_LEVEL_DEBUG,
+            plog(ASL_LEVEL_NOTICE,
                  "deleteallph1: got a ph1 handler...\n");
             if (FSM_STATE_IS_ESTABLISHED(iph1->status))
                 isakmp_info_send_d1(iph1);
@@ -1111,7 +1112,7 @@ vchar_t *rbuf;
        if (r->retry_counter <= 0) {
                ike_session_rem_recvdpkt(r);
                ike_session_del_recvdpkt(r);
-               plog(ASL_LEVEL_DEBUG,
+               plog(ASL_LEVEL_NOTICE,
              "deleted the retransmission packet to %s.\n",
              saddr2str((struct sockaddr *)remote));
        } else {
@@ -1322,8 +1323,7 @@ ike_session_expire_session(ike_session_t *session)
             continue;
         }
 
-        if (FSM_STATE_IS_ESTABLISHED(p2->status))
-            isakmp_info_send_d2(p2);
+        // Don't send a delete, since the ph1 implies the removal of ph2s
         isakmp_ph2expire(p2);
         found++;
     }
@@ -1359,7 +1359,7 @@ ike_session_purgephXbydstaddrwop(struct sockaddr_storage *remote)
                        continue;
                }
             if (cmpsaddrwop(remote, p2->dst) == 0) {
-                plog(ASL_LEVEL_DEBUG,
+                plog(ASL_LEVEL_NOTICE,
                      "in %s... purging Phase 2 structures\n", __FUNCTION__);
                 if (FSM_STATE_IS_ESTABLISHED(p2->status))
                     isakmp_info_send_d2(p2);
@@ -1373,7 +1373,7 @@ ike_session_purgephXbydstaddrwop(struct sockaddr_storage *remote)
                        continue;
                }
             if (cmpsaddrwop(remote, p->remote) == 0) {
-                plog(ASL_LEVEL_DEBUG,
+                plog(ASL_LEVEL_NOTICE,
                      "in %s... purging Phase 1 and related Phase 2 structures\n", __FUNCTION__);
                 ike_session_purge_ph2s_by_ph1(p);
                 if (FSM_STATE_IS_ESTABLISHED(p->status))
@@ -1453,13 +1453,13 @@ ike_session_ph1_force_dpd (struct sockaddr_storage *remote)
                         isakmp_info_send_r_u(p);
                         status = 0;
                     } else {
-                        plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (dpd already in progress).\n");
+                        plog(ASL_LEVEL_NOTICE, "Skipping forced-DPD for Phase 1 (dpd already in progress).\n");
                     }
                     if (p->parent_session) {
                         p->parent_session->controller_awaiting_peer_resp = 1;
                     }
                 } else {
-                    plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
+                    plog(ASL_LEVEL_NOTICE, "Skipping forced-DPD for Phase 1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
                          p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval);
                 }
             }
@@ -1484,12 +1484,12 @@ sweep_sleepwake(void)
         // do the ph1s.
         LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) {
             if (iph1->parent_session && iph1->parent_session->is_asserted) {
-                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's been asserted.\n",
+                plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 1 %s because it's been asserted.\n",
                      isakmp_pindex(&iph1->index, 0));
                 continue;
             }
             if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) {
-                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's already expired.\n",
+                plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 1 %s because it's already expired.\n",
                      isakmp_pindex(&iph1->index, 0));
                 continue;
             }
@@ -1503,7 +1503,7 @@ sweep_sleepwake(void)
                         fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
                         ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1
                         iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
-                        plog(ASL_LEVEL_DEBUG, "Phase 1 %s expired while sleeping: quick deletion.\n",
+                        plog(ASL_LEVEL_NOTICE, "Phase 1 %s expired while sleeping: quick deletion.\n",
                              isakmp_pindex(&iph1->index, 0));
                     }
                 }
@@ -1539,11 +1539,11 @@ sweep_sleepwake(void)
         // do ph2's next
         LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
             if (iph2->parent_session && iph2->parent_session->is_asserted) {
-                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's been asserted.\n");
+                plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 2 because it's been asserted.\n");
                 continue;
             }
             if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
-                plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's already expired.\n");
+                plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 2 because it's already expired.\n");
                 continue;
             }
             if (iph2->sce) {
@@ -1555,7 +1555,7 @@ sweep_sleepwake(void)
                         isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
                         ike_session_stopped_by_controller(iph2->parent_session,
                                                       ike_session_stopped_by_sleepwake);
-                        plog(ASL_LEVEL_DEBUG, "Phase 2 expired while sleeping: quick deletion.\n");
+                        plog(ASL_LEVEL_NOTICE, "Phase 2 expired while sleeping: quick deletion.\n");
                     }
                 }
             }
@@ -1573,3 +1573,41 @@ sweep_sleepwake(void)
        // do the ike_session last
        ike_session_sweep_sleepwake();
 }
+
+uint32_t
+iph1_get_remote_v4_address(phase1_handle_t *iph1)
+{
+       uint32_t address = 0;
+       if (iph1->remote->ss_family == AF_INET) {
+               address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
+       } else if (iph1->remote->ss_family == AF_INET6 &&
+                          iph1->nat64_prefix.length) {
+               if (!nw_nat64_extract_v4(&iph1->nat64_prefix, &((struct sockaddr_in6 *)iph1->remote)->sin6_addr, (struct in_addr *)&address)) {
+                       plog(ASL_LEVEL_ERR, "Failed to extract IPv4 from Phase 1 IPv6 address.\n");
+               }
+       } else {
+               plog(ASL_LEVEL_ERR, "Failed to get IPv4 address for Phase 1 (family=%u, NAT64Prefix=%u)\n",
+                        iph1->remote->ss_family,
+                        iph1->nat64_prefix.length);
+       }
+       return address;
+}
+
+uint32_t
+iph2_get_remote_v4_address(phase2_handle_t *iph2)
+{
+       uint32_t address = 0;
+       if (iph2->dst->ss_family == AF_INET) {
+               address = ((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr;
+       } else if (iph2->dst->ss_family == AF_INET6 &&
+                          iph2->nat64_prefix.length) {
+               if (!nw_nat64_extract_v4(&iph2->nat64_prefix, &((struct sockaddr_in6 *)iph2->dst)->sin6_addr, (struct in_addr *)&address)) {
+                       plog(ASL_LEVEL_ERR, "Failed to extract IPv4 from Phase 2 IPv6 address.\n");
+               }
+       } else {
+               plog(ASL_LEVEL_ERR, "Failed to get IPv4 address for Phase 2 (family=%u, NAT64Prefix=%u)\n",
+                        iph2->dst->ss_family,
+                        iph2->nat64_prefix.length);
+       }
+       return address;
+}