]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/ipsec.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / bsd / netinet6 / ipsec.c
index c5610feed5554afa02a685afac358204f6707fa6..2e11f4515eafe4e78b258daeab7a690c6a2118bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -82,6 +82,7 @@
 #include <sys/bitstring.h>
 
 #include <libkern/OSAtomic.h>
+#include <libkern/sysctl.h>
 
 #include <net/if.h>
 #include <net/route.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
 #include <netinet/ip_ecn.h>
-#if INET6
 #include <netinet6/ip6_ecn.h>
-#endif
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 
 #include <netinet/ip6.h>
-#if INET6
 #include <netinet6/ip6_var.h>
-#endif
 #include <netinet/in_pcb.h>
-#if INET6
 #include <netinet/icmp6.h>
-#endif
 
 #include <netinet6/ipsec.h>
-#if INET6
 #include <netinet6/ipsec6.h>
-#endif
 #include <netinet6/ah.h>
-#if INET6
 #include <netinet6/ah6.h>
-#endif
 #if IPSEC_ESP
 #include <netinet6/esp.h>
-#if INET6
 #include <netinet6/esp6.h>
 #endif
-#endif
 #include <netkey/key.h>
 #include <netkey/keydb.h>
 #include <netkey/key_debug.h>
@@ -172,9 +161,7 @@ void *sleep_wake_handle = NULL;
 bool ipsec_save_wake_pkt = false;
 
 SYSCTL_DECL(_net_inet_ipsec);
-#if INET6
 SYSCTL_DECL(_net_inet6_ipsec6);
-#endif
 /* net.inet.ipsec */
 SYSCTL_STRUCT(_net_inet_ipsec, IPSECCTL_STATS,
     stats, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsecstat, ipsecstat, "");
@@ -214,7 +201,6 @@ SYSCTL_INT(_net_inet_ipsec, OID_AUTO, bypass, CTLFLAG_RD | CTLFLAG_LOCKED, &ipse
 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, esp_port,
     CTLFLAG_RW | CTLFLAG_LOCKED, &esp_udp_encap_port, 0, "");
 
-#if INET6
 struct ipsecstat ipsec6stat;
 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
@@ -243,39 +229,32 @@ SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
     debug, CTLFLAG_RW | CTLFLAG_LOCKED, &ipsec_debug, 0, "");
 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
     esp_randpad, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_randpad, 0, "");
-#endif /* INET6 */
 
 SYSCTL_DECL(_net_link_generic_system);
 
 struct ipsec_wake_pkt_info ipsec_wake_pkt;
 
-static int ipsec_setspidx_interface(struct secpolicyindex *, u_int, struct mbuf *,
+static int ipsec_setspidx_interface(struct secpolicyindex *, u_int8_t, struct mbuf *,
     int, int, int);
-static int ipsec_setspidx_mbuf(struct secpolicyindex *, u_int, u_int,
+static int ipsec_setspidx_mbuf(struct secpolicyindex *, u_int8_t, u_int,
     struct mbuf *, int);
 static int ipsec4_setspidx_inpcb(struct mbuf *, struct inpcb *pcb);
-#if INET6
 static int ipsec6_setspidx_in6pcb(struct mbuf *, struct in6pcb *pcb);
-#endif
 static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int, int);
 static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
 static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
-#if INET6
 static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
 static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
-#endif
 static struct inpcbpolicy *ipsec_newpcbpolicy(void);
 static void ipsec_delpcbpolicy(struct inpcbpolicy *);
 static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
 static int ipsec_set_policy(struct secpolicy **pcb_sp,
     int optname, caddr_t request, size_t len, int priv);
-static void vshiftl(unsigned char *, int, int);
+static void vshiftl(unsigned char *, int, size_t);
 static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
-#if INET6
 static int ipsec64_encapsulate(struct mbuf *, struct secasvar *);
 static int ipsec6_update_routecache_and_output(struct ipsec_output_state *state, struct secasvar *sav);
 static int ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav);
-#endif
 static struct ipsec_tag *ipsec_addaux(struct mbuf *);
 static struct ipsec_tag *ipsec_findaux(struct mbuf *);
 static void ipsec_optaux(struct mbuf *, struct ipsec_tag *);
@@ -283,7 +262,11 @@ int ipsec_send_natt_keepalive(struct secasvar *sav);
 bool ipsec_fill_offload_frame(ifnet_t ifp, struct secasvar *sav, struct ifnet_keepalive_offload_frame *frame, size_t frame_data_offset);
 
 extern bool IOPMCopySleepWakeUUIDKey(char *, size_t);
-extern void *registerSleepWakeInterest(void *, void *, void *);
+
+typedef IOReturn (*IOServiceInterestHandler)( void * target, void * refCon,
+    UInt32 messageType, void * provider,
+    void * messageArgument, vm_size_t argSize );
+extern void *registerSleepWakeInterest(IOServiceInterestHandler, void *, void *);
 
 static int
 sysctl_def_policy SYSCTL_HANDLER_ARGS
@@ -322,7 +305,7 @@ sysctl_def_policy SYSCTL_HANDLER_ARGS
  */
 struct secpolicy *
 ipsec4_getpolicybysock(struct mbuf *m,
-    u_int dir,
+    u_int8_t dir,
     struct socket *so,
     int *error)
 {
@@ -345,11 +328,9 @@ ipsec4_getpolicybysock(struct mbuf *m,
        case PF_INET:
                pcbsp = sotoinpcb(so)->inp_sp;
                break;
-#if INET6
        case PF_INET6:
                pcbsp = sotoin6pcb(so)->in6p_sp;
                break;
-#endif
        }
 
        if (!pcbsp) {
@@ -364,12 +345,10 @@ ipsec4_getpolicybysock(struct mbuf *m,
                /* set spidx in pcb */
                *error = ipsec4_setspidx_inpcb(m, sotoinpcb(so));
                break;
-#if INET6
        case PF_INET6:
                /* set spidx in pcb */
                *error = ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
                break;
-#endif
        default:
                panic("ipsec4_getpolicybysock: unsupported address family\n");
        }
@@ -528,7 +507,7 @@ ipsec4_getpolicybysock(struct mbuf *m,
  */
 struct secpolicy *
 ipsec4_getpolicybyaddr(struct mbuf *m,
-    u_int dir,
+    u_int8_t dir,
     int flag,
     int *error)
 {
@@ -596,7 +575,7 @@ ipsec4_getpolicybyaddr(struct mbuf *m,
  */
 int
 ipsec4_getpolicybyinterface(struct mbuf *m,
-    u_int dir,
+    u_int8_t dir,
     int *flags,
     struct ip_out_args *ipoa,
     struct secpolicy **sp)
@@ -655,7 +634,6 @@ ipsec4_getpolicybyinterface(struct mbuf *m,
 }
 
 
-#if INET6
 /*
  * For OUTBOUND packet having a socket. Searching SPD for packet,
  * and return a pointer to SP.
@@ -668,7 +646,7 @@ ipsec4_getpolicybyinterface(struct mbuf *m,
  */
 struct secpolicy *
 ipsec6_getpolicybysock(struct mbuf *m,
-    u_int dir,
+    u_int8_t dir,
     struct socket *so,
     int *error)
 {
@@ -845,7 +823,7 @@ ipsec6_getpolicybysock(struct mbuf *m,
 
 struct secpolicy *
 ipsec6_getpolicybyaddr(struct mbuf *m,
-    u_int dir,
+    u_int8_t dir,
     int flag,
     int *error)
 {
@@ -905,7 +883,7 @@ ipsec6_getpolicybyaddr(struct mbuf *m,
  */
 int
 ipsec6_getpolicybyinterface(struct mbuf *m,
-    u_int dir,
+    u_int8_t dir,
     int flag,
     struct ip6_out_args *ip6oap,
     int *noipsec,
@@ -965,7 +943,6 @@ ipsec6_getpolicybyinterface(struct mbuf *m,
 
        return 0;
 }
-#endif /* INET6 */
 
 /*
  * set IP address into spidx from mbuf.
@@ -980,7 +957,7 @@ ipsec6_getpolicybyinterface(struct mbuf *m,
 static int
 ipsec_setspidx_mbuf(
        struct secpolicyindex *spidx,
-       u_int dir,
+       u_int8_t dir,
        __unused u_int family,
        struct mbuf *m,
        int needport)
@@ -1011,7 +988,7 @@ bad:
 static int
 ipsec_setspidx_interface(
        struct secpolicyindex *spidx,
-       u_int dir,
+       u_int8_t dir,
        struct mbuf *m,
        int needport,
        int ifindex,
@@ -1092,7 +1069,6 @@ bad:
        return error;
 }
 
-#if INET6
 static int
 ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb)
 {
@@ -1134,7 +1110,6 @@ bad:
        bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
        return error;
 }
-#endif
 
 /*
  * configure security policy index (src/dst/proto/sport/dport)
@@ -1208,7 +1183,6 @@ ipsec_setspidx(struct mbuf *m,
                }
                ipsec4_get_ulp(m, spidx, needport);
                return 0;
-#if INET6
        case 6:
                if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
                        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
@@ -1223,7 +1197,6 @@ ipsec_setspidx(struct mbuf *m,
                }
                ipsec6_get_ulp(m, spidx, needport);
                return 0;
-#endif
        default:
                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
                    printf("ipsec_setspidx: "
@@ -1346,7 +1319,6 @@ ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
        return 0;
 }
 
-#if INET6
 static void
 ipsec6_get_ulp(struct mbuf *m,
     struct secpolicyindex *spidx,
@@ -1375,9 +1347,10 @@ ipsec6_get_ulp(struct mbuf *m,
                return;
        }
 
+       VERIFY(nxt <= UINT8_MAX);
        switch (nxt) {
        case IPPROTO_TCP:
-               spidx->ul_proto = nxt;
+               spidx->ul_proto = (u_int8_t)nxt;
                if (!needport) {
                        break;
                }
@@ -1389,7 +1362,7 @@ ipsec6_get_ulp(struct mbuf *m,
                ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
                break;
        case IPPROTO_UDP:
-               spidx->ul_proto = nxt;
+               spidx->ul_proto = (u_int8_t)nxt;
                if (!needport) {
                        break;
                }
@@ -1403,7 +1376,7 @@ ipsec6_get_ulp(struct mbuf *m,
        case IPPROTO_ICMPV6:
        default:
                /* XXX intermediate headers??? */
-               spidx->ul_proto = nxt;
+               spidx->ul_proto = (u_int8_t)nxt;
                break;
        }
 }
@@ -1448,7 +1421,6 @@ ipsec6_setspidx_ipaddr(struct mbuf *m,
 
        return 0;
 }
-#endif
 
 static struct inpcbpolicy *
 ipsec_newpcbpolicy(void)
@@ -1749,7 +1721,6 @@ ipsec4_delete_pcbpolicy(struct inpcb *inp)
        return 0;
 }
 
-#if INET6
 int
 ipsec6_set_policy(struct in6pcb *in6p,
     int optname,
@@ -1832,7 +1803,6 @@ ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
 
        return 0;
 }
-#endif
 
 /*
  * return current level.
@@ -1867,22 +1837,18 @@ ipsec_get_reqlevel(struct ipsecrequest *isr)
 
        /* set default level */
        switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
-#if INET
        case AF_INET:
                esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
                esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
                ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
                ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
                break;
-#endif
-#if INET6
        case AF_INET6:
                esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
                esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
                ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
                ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
                break;
-#endif /* INET6 */
        default:
                panic("key_get_reqlevel: Unknown family. %d\n",
                    ((struct sockaddr *)&isr->sp->spidx.src)->sa_family);
@@ -2089,7 +2055,6 @@ ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
        return 0;
 }
 
-#if INET6
 /*
  * Check AH/ESP integrity.
  * This function is called from tcp6_input(), udp6_input(),
@@ -2145,7 +2110,6 @@ ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
        /* NOTREACHED */
        return 0;
 }
-#endif
 
 /*
  * compute the byte size to be occupied by IPsec header.
@@ -2207,11 +2171,9 @@ ipsec_hdrsiz(struct secpolicy *sp)
                        case AF_INET:
                                clen += sizeof(struct ip);
                                break;
-#if INET6
                        case AF_INET6:
                                clen += sizeof(struct ip6_hdr);
                                break;
-#endif
                        default:
                                ipseclog((LOG_ERR, "ipsec_hdrsiz: "
                                    "unknown AF %d in IPsec tunnel SA\n",
@@ -2227,7 +2189,7 @@ ipsec_hdrsiz(struct secpolicy *sp)
 
 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
 size_t
-ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
+ipsec4_hdrsiz(struct mbuf *m, u_int8_t dir, struct inpcb *inp)
 {
        struct secpolicy *sp = NULL;
        int error;
@@ -2266,12 +2228,11 @@ ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
        return size;
 }
 
-#if INET6
 /* This function is called from ipsec6_hdrsize_tcp(),
  * and maybe from ip6_forward.()
  */
 size_t
-ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
+ipsec6_hdrsiz(struct mbuf *m, u_int8_t dir, struct in6pcb *in6p)
 {
        struct secpolicy *sp = NULL;
        int error;
@@ -2307,9 +2268,7 @@ ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
 
        return size;
 }
-#endif /*INET6*/
 
-#if INET
 /*
  * encapsulate for ipsec tunnel.
  * ip->ip_src must be fixed later on.
@@ -2319,8 +2278,8 @@ ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
 {
        struct ip *oip;
        struct ip *ip;
-       size_t hlen;
        size_t plen;
+       u_int32_t hlen;
 
        /* can't tunnel between different AFs */
        if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
@@ -2329,13 +2288,6 @@ ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
                m_freem(m);
                return EINVAL;
        }
-#if 0
-       /* XXX if the dst is myself, perform nothing. */
-       if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
-               m_freem(m);
-               return EINVAL;
-       }
-#endif
 
        if (m->m_len < sizeof(*ip)) {
                panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
@@ -2411,7 +2363,7 @@ ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
        }
        ip->ip_p = IPPROTO_IPIP;
        if (plen + sizeof(struct ip) < IP_MAXPACKET) {
-               ip->ip_len = htons(plen + sizeof(struct ip));
+               ip->ip_len = htons((u_int16_t)(plen + sizeof(struct ip)));
        } else {
                ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
                    "leave ip_len as is (invalid packet)\n"));
@@ -2432,9 +2384,7 @@ ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
        return 0;
 }
 
-#endif /*INET*/
 
-#if INET6
 int
 ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
 {
@@ -2449,13 +2399,6 @@ ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
                m_freem(m);
                return EINVAL;
        }
-#if 0
-       /* XXX if the dst is myself, perform nothing. */
-       if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
-               m_freem(m);
-               return EINVAL;
-       }
-#endif
 
        plen = m->m_pkthdr.len;
 
@@ -2498,7 +2441,7 @@ ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
        /* ECN consideration. */
        ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
        if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr)) {
-               ip6->ip6_plen = htons(plen);
+               ip6->ip6_plen = htons((u_int16_t)plen);
        } else {
                /* ip6->ip6_plen will be updated in ip6_output() */
        }
@@ -2529,13 +2472,6 @@ ipsec64_encapsulate(struct mbuf *m, struct secasvar *sav)
                m_freem(m);
                return EINVAL;
        }
-#if 0
-       /* XXX if the dst is myself, perform nothing. */
-       if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
-               m_freem(m);
-               return EINVAL;
-       }
-#endif
 
        plen = m->m_pkthdr.len;
        ip6 = mtod(m, struct ip6_hdr *);
@@ -2583,12 +2519,12 @@ ipsec64_encapsulate(struct mbuf *m, struct secasvar *sav)
 
        /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
        /* ECN consideration. */
-       ip64_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &ip6->ip6_flow);
+       ip64_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &ip6i->ip6_flow);
 
        if (plen + sizeof(struct ip) < IP_MAXPACKET) {
-               ip->ip_len = htons(plen + sizeof(struct ip));
+               ip->ip_len = htons((u_int16_t)(plen + sizeof(struct ip)));
        } else {
-               ip->ip_len = htons(plen);
+               ip->ip_len = htons((u_int16_t)plen);
                ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
                    "leave ip_len as is (invalid packet)\n"));
        }
@@ -2714,13 +2650,13 @@ ipsec6_update_routecache_and_output(
                return error;
        }
        ip6 = mtod(state->m, struct ip6_hdr *);
-       ip6->ip6_plen = htons(plen);
+       ip6->ip6_plen = htons((u_int16_t)plen);
 
        ipsec_set_pkthdr_for_interface(sav->sah->ipsec_if, state->m, AF_INET6);
        ipsec_set_ip6oa_for_interface(sav->sah->ipsec_if, &ip6oa);
 
        /* Increment statistics */
-       ifnet_stat_increment_out(sav->sah->ipsec_if, 1, mbuf_pkthdr_len(state->m), 0);
+       ifnet_stat_increment_out(sav->sah->ipsec_if, 1, (u_int32_t)mbuf_pkthdr_len(state->m), 0);
 
        /* Send to ip6_output */
        bzero(&ro6_new, sizeof(ro6_new));
@@ -2752,8 +2688,8 @@ ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav)
        struct ip6_hdr *ip6;
        struct ip *oip;
        struct ip *ip;
-       size_t hlen;
        size_t plen;
+       u_int32_t hlen;
 
        m = state->m;
        if (!m) {
@@ -2767,13 +2703,6 @@ ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav)
                m_freem(m);
                return EINVAL;
        }
-#if 0
-       /* XXX if the dst is myself, perform nothing. */
-       if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
-               m_freem(m);
-               return EINVAL;
-       }
-#endif
 
        if (m->m_len < sizeof(*ip)) {
                panic("ipsec46_encapsulate: assumption failed (first mbuf length)");
@@ -2855,9 +2784,9 @@ ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav)
 
        /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
        /* ECN consideration. */
-       ip46_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &ip->ip_tos);
+       ip46_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip->ip_tos);
        if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr)) {
-               ip6->ip6_plen = htons(plen);
+               ip6->ip6_plen = htons((u_int16_t)plen);
        } else {
                /* ip6->ip6_plen will be updated in ip6_output() */
        }
@@ -2873,8 +2802,6 @@ ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav)
        return 0;
 }
 
-#endif /*INET6*/
-
 /*
  * Check the variable replay window.
  * ipsec_chkreplay() performs replay check before ICV verification.
@@ -2890,9 +2817,9 @@ ipsec_chkreplay(u_int32_t seq, struct secasvar *sav, u_int8_t replay_index)
 {
        const struct secreplay *replay;
        u_int32_t diff;
-       int fr;
-       u_int32_t wsizeb;       /* constant: bits of window size */
-       int frlast;             /* constant: last frame */
+       size_t fr;
+       size_t wsizeb;       /* constant: bits of window size */
+       size_t frlast;       /* constant: last frame */
 
 
        /* sanity check */
@@ -2962,9 +2889,9 @@ ipsec_updatereplay(u_int32_t seq, struct secasvar *sav, u_int8_t replay_index)
 {
        struct secreplay *replay;
        u_int32_t diff;
-       int fr;
-       u_int32_t wsizeb;       /* constant: bits of window size */
-       int frlast;             /* constant: last frame */
+       size_t fr;
+       size_t wsizeb;       /* constant: bits of window size */
+       size_t frlast;             /* constant: last frame */
 
        /* sanity check */
        if (sav == NULL) {
@@ -3065,9 +2992,10 @@ ok:
  *     wsize:  buffer size (bytes).
  */
 static void
-vshiftl(unsigned char *bitmap, int nbit, int wsize)
+vshiftl(unsigned char *bitmap, int nbit, size_t wsize)
 {
-       int s, j, i;
+       size_t i;
+       int s, j;
        unsigned char over;
 
        for (j = 0; j < nbit; j += 8) {
@@ -3113,7 +3041,6 @@ ipsec4_logpacketstr(struct ip *ip, u_int32_t spi)
        return buf;
 }
 
-#if INET6
 const char *
 ipsec6_logpacketstr(struct ip6_hdr *ip6, u_int32_t spi)
 {
@@ -3139,7 +3066,6 @@ ipsec6_logpacketstr(struct ip6_hdr *ip6, u_int32_t spi)
 
        return buf;
 }
-#endif /*INET6*/
 
 const char *
 ipsec_logsastr(struct secasvar *sav)
@@ -3166,9 +3092,7 @@ ipsec_logsastr(struct secasvar *sav)
                snprintf(p, sizeof(buf) - (p - buf),
                    "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
                    s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
-       }
-#if INET6
-       else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
+       } else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
                snprintf(p, sizeof(buf) - (p - buf),
                    "src=%s",
                    ip6_sprintf(&((struct sockaddr_in6 *)&saidx->src)->sin6_addr));
@@ -3179,7 +3103,6 @@ ipsec_logsastr(struct secasvar *sav)
                    " dst=%s",
                    ip6_sprintf(&((struct sockaddr_in6 *)&saidx->dst)->sin6_addr));
        }
-#endif
        while (p && *p) {
                p++;
        }
@@ -3496,7 +3419,7 @@ ipsec4_output(struct ipsec_output_state *state, struct secpolicy *sp, __unused i
                            isr->saidx.mode == IPSEC_MODE_TRANSPORT) {
                                if (ip->ip_p == IPPROTO_UDP) {
                                        struct udphdr  *udp;
-                                       size_t hlen;
+                                       u_int32_t hlen;
 #ifdef _IP_VHL
                                        hlen = IP_VHL_HL(ip->ip_vhl) << 2;
 #else
@@ -3566,7 +3489,6 @@ bad:
 
 #endif
 
-#if INET6
 /*
  * IPsec output logic for IPv6, transport mode.
  */
@@ -3578,8 +3500,8 @@ ipsec6_output_trans_internal(
        struct mbuf *mprev)
 {
        struct ip6_hdr *ip6;
+       size_t plen;
        int error = 0;
-       int plen;
 
        /* validity check */
        if (sav == NULL || sav->sah == NULL) {
@@ -3633,7 +3555,7 @@ ipsec6_output_trans_internal(
                goto bad;
        }
        ip6 = mtod(state->m, struct ip6_hdr *);
-       ip6->ip6_plen = htons(plen);
+       ip6->ip6_plen = htons((u_int16_t)plen);
 
        return 0;
 bad:
@@ -3787,10 +3709,10 @@ static int
 ipsec6_output_tunnel_internal(struct ipsec_output_state *state, struct secasvar *sav, int *must_be_last)
 {
        struct ip6_hdr *ip6;
-       int error = 0;
-       int plen;
        struct sockaddr_in6* dst6;
        struct route_in6 *ro6;
+       size_t plen;
+       int error = 0;
 
        /* validity check */
        if (sav == NULL || sav->sah == NULL || sav->sah->saidx.mode != IPSEC_MODE_TUNNEL) {
@@ -4043,7 +3965,7 @@ ipsec6_output_tunnel_internal(struct ipsec_output_state *state, struct secasvar
                goto bad;
        }
        ip6 = mtod(state->m, struct ip6_hdr *);
-       ip6->ip6_plen = htons(plen);
+       ip6->ip6_plen = htons((u_int16_t)plen);
 done:
        return 0;
 
@@ -4260,7 +4182,6 @@ bad:
        state->m = NULL;
        return error;
 }
-#endif /*INET6*/
 
 #if INET
 /*
@@ -4308,7 +4229,6 @@ ipsec4_splithdr(struct mbuf *m)
 }
 #endif
 
-#if INET6
 struct mbuf *
 ipsec6_splithdr(struct mbuf *m)
 {
@@ -4345,7 +4265,6 @@ ipsec6_splithdr(struct mbuf *m)
        }
        return m;
 }
-#endif
 
 /* validate inbound IPsec tunnel packet. */
 int
@@ -4473,7 +4392,6 @@ ipsec4_tunnel_validate(
        return 1;
 }
 
-#if INET6
 /* validate inbound IPsec tunnel packet. */
 int
 ipsec6_tunnel_validate(
@@ -4584,7 +4502,6 @@ ipsec6_tunnel_validate(
 
        return 1;
 }
-#endif
 
 /*
  * Make a mbuf chain for encryption.
@@ -4935,8 +4852,8 @@ ipsec_send_natt_keepalive(
                bzero(m_mtod(m), m->m_len);
                m->m_pkthdr.len = m->m_len;
 
-               ip->ip_len = m->m_len;
-               ip->ip_ttl = ip_defttl;
+               ip->ip_len = (u_short)m->m_len;
+               ip->ip_ttl = (u_char)ip_defttl;
                ip->ip_p = IPPROTO_UDP;
                if (sav->sah->dir != IPSEC_DIR_INBOUND) {
                        ip->ip_src = ((struct sockaddr_in*)&sav->sah->saidx.src)->sin_addr;
@@ -4998,7 +4915,7 @@ ipsec_send_natt_keepalive(
                ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
                ip6->ip6_vfc |= IPV6_VERSION;
                ip6->ip6_nxt = IPPROTO_UDP;
-               ip6->ip6_hlim = ip6_defhlim;
+               ip6->ip6_hlim = (u_int8_t)ip6_defhlim;
                ip6->ip6_plen = htons(sizeof(struct udphdr) + 1);
                if (sav->sah->dir != IPSEC_DIR_INBOUND) {
                        ip6->ip6_src = ((struct sockaddr_in6 *)&sav->sah->saidx.src)->sin6_addr;
@@ -5091,7 +5008,7 @@ ipsec_fill_offload_frame(ifnet_t ifp,
        ip = (__typeof__(ip))(void *)(data + frame_data_offset);
        uh = (__typeof__(uh))(void *)(data + frame_data_offset + sizeof(*ip));
 
-       frame->length = frame_data_offset + sizeof(struct udpiphdr) + 1;
+       frame->length = (u_int8_t)(frame_data_offset + sizeof(struct udpiphdr) + 1);
        frame->type = IFNET_KEEPALIVE_OFFLOAD_FRAME_IPSEC;
        frame->ether_type = IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV4;
 
@@ -5117,7 +5034,7 @@ ipsec_fill_offload_frame(ifnet_t ifp,
        } else {
                ip->ip_id = ip_randomid();
        }
-       ip->ip_ttl = ip_defttl;
+       ip->ip_ttl = (u_char)ip_defttl;
        ip->ip_p = IPPROTO_UDP;
        ip->ip_sum = 0;
        if (sav->sah->dir != IPSEC_DIR_INBOUND) {
@@ -5144,7 +5061,7 @@ ipsec_fill_offload_frame(ifnet_t ifp,
        } else if (sav->natt_interval != 0) {
                frame->interval = sav->natt_interval;
        } else {
-               frame->interval = natt_keepalive_interval;
+               frame->interval = (u_int16_t)natt_keepalive_interval;
        }
        return TRUE;
 }
@@ -5198,7 +5115,7 @@ ipsec_save_wake_packet(struct mbuf *wake_mbuf, u_int32_t spi, u_int32_t seq)
                goto done;
        }
 
-       u_int16_t max_len = (wake_mbuf->m_pkthdr.len > IPSEC_MAX_WAKE_PKT_LEN) ? IPSEC_MAX_WAKE_PKT_LEN : wake_mbuf->m_pkthdr.len;
+       u_int16_t max_len = (wake_mbuf->m_pkthdr.len > IPSEC_MAX_WAKE_PKT_LEN) ? IPSEC_MAX_WAKE_PKT_LEN : (u_int16_t)wake_mbuf->m_pkthdr.len;
        m_copydata(wake_mbuf, 0, max_len, (void *)ipsec_wake_pkt.wake_pkt);
        ipsec_wake_pkt.wake_pkt_len = max_len;
 
@@ -5212,11 +5129,19 @@ ipsec_save_wake_packet(struct mbuf *wake_mbuf, u_int32_t spi, u_int32_t seq)
            ipsec_wake_pkt.wake_pkt_seq,
            ipsec_wake_pkt.wake_pkt_len));
 
-       struct kev_msg ev_msg = { 0 };
+       struct kev_msg ev_msg;
+       bzero(&ev_msg, sizeof(ev_msg));
+
        ev_msg.vendor_code      = KEV_VENDOR_APPLE;
        ev_msg.kev_class        = KEV_NETWORK_CLASS;
        ev_msg.kev_subclass     = KEV_IPSEC_SUBCLASS;
-       ev_msg.kev_subclass     = KEV_IPSEC_WAKE_PACKET;
+       ev_msg.event_code       = KEV_IPSEC_WAKE_PACKET;
+
+       struct ipsec_wake_pkt_event_data event_data;
+       strlcpy(event_data.wake_uuid, ipsec_wake_pkt.wake_uuid, sizeof(event_data.wake_uuid));
+       ev_msg.dv[0].data_ptr           = &event_data;
+       ev_msg.dv[0].data_length        = sizeof(event_data);
+
        int result = kev_post_msg(&ev_msg);
        if (result != 0) {
                os_log_error(OS_LOG_DEFAULT, "%s: kev_post_msg() failed with error %d for wake uuid %s",
@@ -5269,18 +5194,33 @@ ipsec_sleep_wake_handler(void *target, void *refCon, UInt32 messageType,
 #pragma unused(target, refCon, provider, messageArgument, argSize)
        switch (messageType) {
        case kIOMessageSystemWillSleep:
+       {
                ipsec_get_local_ports();
+               ipsec_save_wake_pkt = false;
                memset(&ipsec_wake_pkt, 0, sizeof(ipsec_wake_pkt));
                IOPMCopySleepWakeUUIDKey(ipsec_wake_pkt.wake_uuid,
                    sizeof(ipsec_wake_pkt.wake_uuid));
                ipseclog((LOG_NOTICE,
                    "ipsec: system will sleep, uuid: %s", ipsec_wake_pkt.wake_uuid));
                break;
-       case kIOMessageSystemWillPowerOn:
-               ipsec_save_wake_pkt = true;
-               ipseclog((LOG_NOTICE,
-                   "ipsec: system will powered on, uuid: %s", ipsec_wake_pkt.wake_uuid));
+       }
+       case kIOMessageSystemHasPoweredOn:
+       {
+               char wake_reason[128] = {0};
+               size_t size = sizeof(wake_reason);
+               if (kernel_sysctlbyname("kern.wakereason", wake_reason, &size, NULL, 0) == 0) {
+                       if (strnstr(wake_reason, "wlan", size) == 0 ||
+                           strnstr(wake_reason, "WL.OutboxNotEmpty", size) == 0 ||
+                           strnstr(wake_reason, "baseband", size) == 0 ||
+                           strnstr(wake_reason, "bluetooth", size) == 0 ||
+                           strnstr(wake_reason, "BT.OutboxNotEmpty", size) == 0) {
+                               ipsec_save_wake_pkt = true;
+                               ipseclog((LOG_NOTICE,
+                                   "ipsec: system has powered on, uuid: %s reason %s", ipsec_wake_pkt.wake_uuid, wake_reason));
+                       }
+               }
                break;
+       }
        default:
                break;
        }