X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/eb6b6ca394357805f2bdba989abae309f718b4d8..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/bsd/netinet6/ipsec.c diff --git a/bsd/netinet6/ipsec.c b/bsd/netinet6/ipsec.c index c5610feed..2e11f4515 100644 --- a/bsd/netinet6/ipsec.c +++ b/bsd/netinet6/ipsec.c @@ -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 #include +#include #include #include @@ -96,35 +97,23 @@ #include #include #include -#if INET6 #include -#endif #include #include #include -#if INET6 #include -#endif #include -#if INET6 #include -#endif #include -#if INET6 #include -#endif #include -#if INET6 #include -#endif #if IPSEC_ESP #include -#if INET6 #include #endif -#endif #include #include #include @@ -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; }