]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/esp_input.c
xnu-2782.30.5.tar.gz
[apple/xnu.git] / bsd / netinet6 / esp_input.c
index 7470d023efee29fa37812e5af25346990098cada..c8a809490c863549cfd8ba5a469e9f0f45cbc516 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -76,6 +76,7 @@
 #include <sys/syslog.h>
 
 #include <net/if.h>
+#include <net/if_ipsec.h>
 #include <net/route.h>
 #include <kern/cpu_number.h>
 #include <kern/locks.h>
 extern lck_mtx_t  *sadb_mutex;
 
 #if INET
-extern struct protosw inetsw[];
-
 #define ESPMAXLEN \
        (sizeof(struct esp) < sizeof(struct newesp) \
                ? sizeof(struct newesp) : sizeof(struct esp))
@@ -229,7 +228,8 @@ esp4_input(m, off)
                goto bad;
        }
        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-               printf("DP esp4_input called to allocate SA:%p\n", sav));
+           printf("DP esp4_input called to allocate SA:0x%llx\n",
+           (uint64_t)VM_KERNEL_ADDRPERM(sav)));
        if (sav->state != SADB_SASTATE_MATURE
         && sav->state != SADB_SASTATE_DYING) {
                ipseclog((LOG_DEBUG,
@@ -512,14 +512,10 @@ noreplaycheck:
                } else if (ifamily == AF_INET6) {
                        struct sockaddr_in6 *ip6addr;
 
-#ifndef PULLDOWN_TEST
                        /*
                         * m_pullup is prohibited in KAME IPv6 input processing
                         * but there's no other way!
                         */
-#else
-                       /* okay to pullup in m_pulldown style */
-#endif
                        if (m->m_len < sizeof(*ip6)) {
                                m = m_pullup(m, sizeof(*ip6));
                                if (!m) {
@@ -582,6 +578,16 @@ noreplaycheck:
                /* Clear the csum flags, they can't be valid for the inner headers */
                m->m_pkthdr.csum_flags = 0;
 
+               // Input via IPSec interface
+               if (sav->sah->ipsec_if != NULL) {
+                       if (ipsec_inject_inbound_packet(sav->sah->ipsec_if, m) == 0) {
+                               m = NULL;
+                               goto done;
+                       } else {
+                               goto bad;
+                       }
+               }
+               
                if (sav->utun_in_fn) {
                        if (!(sav->utun_in_fn(sav->utun_pcb, &m, ifamily == AF_INET ? PF_INET : PF_INET6))) {
                                m = NULL;
@@ -682,6 +688,20 @@ noreplaycheck:
                                struct ip *, ip, struct ifnet *, m->m_pkthdr.rcvif,
                                struct ip *, ip, struct ip6_hdr *, NULL);
 
+                       // Input via IPSec interface
+                       if (sav->sah->ipsec_if != NULL) {
+                               ip->ip_len = htons(ip->ip_len + hlen);
+                               ip->ip_off = htons(ip->ip_off);
+                               ip->ip_sum = 0;
+                               ip->ip_sum = ip_cksum_hdr_in(m, hlen);
+                               if (ipsec_inject_inbound_packet(sav->sah->ipsec_if, m) == 0) {
+                                       m = NULL;
+                                       goto done;
+                               } else {
+                                       goto bad;
+                               }
+                       }
+                       
                        if (sav->utun_in_fn) {
                                if (!(sav->utun_in_fn(sav->utun_pcb, &m, PF_INET))) {
                                        m = NULL;
@@ -696,9 +716,11 @@ noreplaycheck:
                m = NULL;
        }
 
+done:
        if (sav) {
                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-                       printf("DP esp4_input call free SA:%p\n", sav));
+                   printf("DP esp4_input call free SA:0x%llx\n",
+                   (uint64_t)VM_KERNEL_ADDRPERM(sav)));
                key_freesav(sav, KEY_SADB_UNLOCKED);
        }
        IPSEC_STAT_INCREMENT(ipsecstat.in_success);
@@ -707,7 +729,8 @@ noreplaycheck:
 bad:
        if (sav) {
                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-                       printf("DP esp4_input call free SA:%p\n", sav));
+                   printf("DP esp4_input call free SA:0x%llx\n",
+                   (uint64_t)VM_KERNEL_ADDRPERM(sav)));
                key_freesav(sav, KEY_SADB_UNLOCKED);
        }
        if (m)
@@ -779,7 +802,8 @@ esp6_input(struct mbuf **mp, int *offp, int proto)
                goto bad;
        }
        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-               printf("DP esp6_input called to allocate SA:%p\n", sav));
+           printf("DP esp6_input called to allocate SA:0x%llx\n",
+           (uint64_t)VM_KERNEL_ADDRPERM(sav)));
        if (sav->state != SADB_SASTATE_MATURE
         && sav->state != SADB_SASTATE_DYING) {
                ipseclog((LOG_DEBUG,
@@ -1045,6 +1069,17 @@ noreplaycheck:
                        }
                }
 
+               // Input via IPSec interface
+               if (sav->sah->ipsec_if != NULL) {
+                       if (ipsec_inject_inbound_packet(sav->sah->ipsec_if, m) == 0) {
+                               m = NULL;
+                               nxt = IPPROTO_DONE;
+                               goto done;
+                       } else {
+                               goto bad;
+                       }
+               }
+               
                if (sav->utun_in_fn) {
                        if (!(sav->utun_in_fn(sav->utun_pcb, &m, PF_INET6))) {
                                m = NULL;
@@ -1152,6 +1187,17 @@ noreplaycheck:
                        goto bad;
                }
 
+               // Input via IPSec interface
+               if (sav->sah->ipsec_if != NULL) {
+                       if (ipsec_inject_inbound_packet(sav->sah->ipsec_if, m) == 0) {
+                               m = NULL;
+                               nxt = IPPROTO_DONE;
+                               goto done;
+                       } else {
+                               goto bad;
+                       }
+               }
+               
                if (sav->utun_in_fn) {
                        if (!(sav->utun_in_fn(sav->utun_pcb, &m, PF_INET6))) {
                                m = NULL;
@@ -1161,12 +1207,13 @@ noreplaycheck:
                }
        }
 
+done:
        *offp = off;
        *mp = m;
-
        if (sav) {
                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-                       printf("DP esp6_input call free SA:%p\n", sav));
+                   printf("DP esp6_input call free SA:0x%llx\n",
+                   (uint64_t)VM_KERNEL_ADDRPERM(sav)));
                key_freesav(sav, KEY_SADB_UNLOCKED);
        }
        IPSEC_STAT_INCREMENT(ipsec6stat.in_success);
@@ -1175,7 +1222,8 @@ noreplaycheck:
 bad:
        if (sav) {
                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-                       printf("DP esp6_input call free SA:%p\n", sav));
+                   printf("DP esp6_input call free SA:0x%llx\n",
+                   (uint64_t)VM_KERNEL_ADDRPERM(sav)));
                key_freesav(sav, KEY_SADB_UNLOCKED);
        }
        if (m)