+ KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_END, 3,0,0,0,0);
+
+ /* translate encapsulated UDP port ? */
+ if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0) {
+ struct udphdr *udp;
+
+ if (nxt != IPPROTO_UDP) { /* not UPD packet - drop it */
+ IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
+ goto bad;
+ }
+
+ if (m->m_len < off + sizeof(struct udphdr)) {
+ m = m_pullup(m, off + sizeof(struct udphdr));
+ if (!m) {
+ ipseclog((LOG_DEBUG,
+ "IPv4 ESP input: can't pullup UDP header in esp4_input\n"));
+ IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
+ goto bad;
+ }
+ ip = mtod(m, struct ip *);
+ }
+ udp = (struct udphdr *)(void *)(((u_int8_t *)ip) + off);
+
+ lck_mtx_lock(sadb_mutex);
+ if (sav->natt_encapsulated_src_port == 0) {
+ sav->natt_encapsulated_src_port = udp->uh_sport;
+ } else if (sav->natt_encapsulated_src_port != udp->uh_sport) { /* something wrong */
+ IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
+ lck_mtx_unlock(sadb_mutex);
+ goto bad;
+ }
+ lck_mtx_unlock(sadb_mutex);
+ udp->uh_sport = htons(sav->remote_ike_port);
+ udp->uh_sum = 0;
+ }
+
+ DTRACE_IP6(receive, struct mbuf *, m, struct inpcb *, NULL,
+ struct ip *, ip, struct ifnet *, m->m_pkthdr.rcvif,
+ struct ip *, ip, struct ip6_hdr *, NULL);
+
+ // Input via IPsec interface legacy path
+ if (sav->sah->ipsec_if != NULL) {
+ int mlen;
+ if ((mlen = m_length2(m, NULL)) < hlen) {
+ ipseclog((LOG_DEBUG,
+ "IPv4 ESP input: decrypted packet too short %d < %d\n",
+ mlen, hlen));
+ IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
+ goto bad;
+ }
+ 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);
+
+ // Return mbuf
+ if (interface != NULL &&
+ interface == sav->sah->ipsec_if) {
+ out_m = m;
+ goto done;
+ }
+
+ if (ipsec_inject_inbound_packet(sav->sah->ipsec_if, m) == 0) {
+ m = NULL;
+ goto done;
+ } else {
+ goto bad;
+ }
+ }
+
+ ip_proto_dispatch_in(m, off, nxt, 0);
+ } else {