]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/esp_output.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / bsd / netinet6 / esp_output.c
index 9401200f33ba5dab7507ea9d25b8a5dc34266e63..c867a5ce9dd99020179a15ee191e415afdd923aa 100644 (file)
 #include <netinet/tcp.h>
 #include <netinet/in_tclass.h>
 
-#if INET6
 #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>
 #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
 #include <netinet6/esp.h>
-#if INET6
 #include <netinet6/esp6.h>
-#endif
 #include <netkey/key.h>
 #include <netkey/keydb.h>
 
@@ -257,7 +249,7 @@ esp_output(
        struct tcphdr th = {};
        u_int32_t spi;
        u_int32_t seq;
-       u_int32_t inner_payload_len = 0;
+       size_t inner_payload_len = 0;
        u_int8_t inner_protocol = 0;
        u_int8_t nxt = 0;
        size_t plen;    /*payload length to be encrypted*/
@@ -274,18 +266,14 @@ esp_output(
 
        KERNEL_DEBUG(DBG_FNC_ESPOUT | DBG_FUNC_START, sav->ivlen, 0, 0, 0, 0);
        switch (af) {
-#if INET
        case AF_INET:
                afnumber = 4;
                stat = &ipsecstat;
                break;
-#endif
-#if INET6
        case AF_INET6:
                afnumber = 6;
                stat = &ipsec6stat;
                break;
-#endif
        default:
                ipseclog((LOG_ERR, "esp_output: unsupported af %d\n", af));
                KERNEL_DEBUG(DBG_FNC_ESPOUT | DBG_FUNC_END, 1, 0, 0, 0, 0);
@@ -297,22 +285,18 @@ esp_output(
            SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) {
                u_int8_t dscp = 0;
                switch (af) {
-#if INET
                case AF_INET:
                {
                        struct ip *ip = mtod(m, struct ip *);
                        dscp = ip->ip_tos >> IPTOS_DSCP_SHIFT;
                        break;
                }
-#endif /*INET*/
-#if INET6
                case AF_INET6:
                {
                        struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
                        dscp = (ntohl(ip6->ip6_flow) & IP6FLOW_DSCP_MASK) >> IP6FLOW_DSCP_SHIFT;
                        break;
                }
-#endif /*INET6*/
                default:
                        panic("esp_output: should not reach here");
                }
@@ -322,7 +306,6 @@ esp_output(
        /* some sanity check */
        if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay[traffic_class] == NULL) {
                switch (af) {
-#if INET
                case AF_INET:
                {
                        struct ip *ip;
@@ -336,15 +319,12 @@ esp_output(
                        IPSEC_STAT_INCREMENT(ipsecstat.out_inval);
                        break;
                }
-#endif /*INET*/
-#if INET6
                case AF_INET6:
                        ipseclog((LOG_DEBUG, "esp6_output: internal error: "
                            "sav->replay is null: SPI=%u\n",
                            (u_int32_t)ntohl(sav->spi)));
                        IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
                        break;
-#endif /*INET6*/
                default:
                        panic("esp_output: should not reach here");
                }
@@ -375,12 +355,8 @@ esp_output(
                 * chase the header chain.
                 * XXX sequential number
                 */
-#if INET
                struct ip *ip = NULL;
-#endif
-#if INET6
                struct ip6_hdr *ip6 = NULL;
-#endif
                size_t esplen; /* sizeof(struct esp/newesp) */
                size_t hlen = 0; /* ip header len */
 
@@ -414,7 +390,6 @@ esp_output(
                }
 
                switch (af) {
-#if INET
                case AF_INET:
                        ip = mtod(m, struct ip *);
 #ifdef _IP_VHL
@@ -423,13 +398,10 @@ esp_output(
                        hlen = ip->ip_hl << 2;
 #endif
                        break;
-#endif
-#if INET6
                case AF_INET6:
                        ip6 = mtod(m, struct ip6_hdr *);
                        hlen = sizeof(*ip6);
                        break;
-#endif
                }
 
                /* grab info for packet logging */
@@ -459,7 +431,7 @@ esp_output(
                                        if (inner_protocol == IPPROTO_TCP) {
                                                if ((int)(iphlen + sizeof(th)) <=
                                                    (m->m_pkthdr.len - m->m_len)) {
-                                                       m_copydata(md, iphlen, sizeof(th), (u_int8_t *)&th);
+                                                       m_copydata(md, (int)iphlen, sizeof(th), (u_int8_t *)&th);
                                                }
 
                                                inner_payload_len = m->m_pkthdr.len - m->m_len - iphlen - (th.th_off << 2);
@@ -475,7 +447,7 @@ esp_output(
                                        if (inner_protocol == IPPROTO_TCP) {
                                                if ((int)(iphlen + sizeof(th)) <=
                                                    m->m_pkthdr.len) {
-                                                       m_copydata(m, iphlen, sizeof(th), (u_int8_t *)&th);
+                                                       m_copydata(m, (int)iphlen, sizeof(th), (u_int8_t *)&th);
                                                }
 
                                                inner_payload_len = m->m_pkthdr.len - iphlen - (th.th_off << 2);
@@ -549,7 +521,8 @@ esp_output(
                                error = ENOBUFS;
                                goto fail;
                        }
-                       n->m_len = esphlen;
+                       VERIFY(esphlen <= INT32_MAX);
+                       n->m_len = (int)esphlen;
                        mprev->m_next = n;
                        n->m_next = md;
                        m->m_pkthdr.len += esphlen;
@@ -573,10 +546,9 @@ esp_output(
                }
 
                switch (af) {
-#if INET
                case AF_INET:
                        if (esphlen < (IP_MAXPACKET - ntohs(ip->ip_len))) {
-                               ip->ip_len = htons(ntohs(ip->ip_len) + esphlen);
+                               ip->ip_len = htons(ntohs(ip->ip_len) + (u_short)esphlen);
                        } else {
                                ipseclog((LOG_ERR,
                                    "IPv4 ESP output: size exceeds limit\n"));
@@ -586,12 +558,9 @@ esp_output(
                                goto fail;
                        }
                        break;
-#endif
-#if INET6
                case AF_INET6:
                        /* total packet length will be computed in ip6_output() */
                        break;
-#endif
                }
        }
 
@@ -627,9 +596,7 @@ esp_output(
                /*
                 * find the last mbuf. make some room for ESP trailer.
                 */
-#if INET
                struct ip *ip = NULL;
-#endif
                size_t padbound;
                u_char *extend;
                int i;
@@ -652,16 +619,12 @@ esp_output(
 
                /* random padding */
                switch (af) {
-#if INET
                case AF_INET:
                        randpadmax = ip4_esp_randpad;
                        break;
-#endif
-#if INET6
                case AF_INET6:
                        randpadmax = ip6_esp_randpad;
                        break;
-#endif
                default:
                        randpadmax = -1;
                        break;
@@ -669,10 +632,10 @@ esp_output(
                if (randpadmax < 0 || plen + extendsiz >= randpadmax) {
                        ;
                } else {
-                       int pad;
+                       size_t pad;
 
                        /* round */
-                       randpadmax = (randpadmax / padbound) * padbound;
+                       randpadmax = (int)((randpadmax / padbound) * padbound);
                        pad = (randpadmax - plen + extendsiz) / padbound;
 
                        if (pad > 0) {
@@ -695,12 +658,6 @@ esp_output(
                        }
                }
 
-#if DIAGNOSTIC
-               if (extendsiz > MLEN || extendsiz >= 256) {
-                       panic("extendsiz too big in esp_output");
-               }
-#endif
-
                n = m;
                while (n->m_next) {
                        n = n->m_next;
@@ -713,7 +670,7 @@ esp_output(
                 */
                if (!(n->m_flags & M_EXT) && extendsiz < M_TRAILINGSPACE(n)) {
                        extend = mtod(n, u_char *) + n->m_len;
-                       n->m_len += extendsiz;
+                       n->m_len += (int)extendsiz;
                        m->m_pkthdr.len += extendsiz;
                } else {
                        struct mbuf *nn;
@@ -727,7 +684,8 @@ esp_output(
                                goto fail;
                        }
                        extend = mtod(nn, u_char *);
-                       nn->m_len = extendsiz;
+                       VERIFY(extendsiz <= INT_MAX);
+                       nn->m_len = (int)extendsiz;
                        nn->m_next = NULL;
                        n->m_next = nn;
                        n = nn;
@@ -771,15 +729,15 @@ esp_output(
                esptail = (struct esptail *)
                    (mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
                esptail->esp_nxt = nxt;
-               esptail->esp_padlen = extendsiz - 2;
+               VERIFY((extendsiz - 2) <= UINT8_MAX);
+               esptail->esp_padlen = (u_int8_t)(extendsiz - 2);
 
                /* modify IP header (for ESP header part only) */
                switch (af) {
-#if INET
                case AF_INET:
                        ip = mtod(m, struct ip *);
                        if (extendsiz < (IP_MAXPACKET - ntohs(ip->ip_len))) {
-                               ip->ip_len = htons(ntohs(ip->ip_len) + extendsiz);
+                               ip->ip_len = htons(ntohs(ip->ip_len) + (u_short)extendsiz);
                        } else {
                                ipseclog((LOG_ERR,
                                    "IPv4 ESP output: size exceeds limit\n"));
@@ -789,12 +747,9 @@ esp_output(
                                goto fail;
                        }
                        break;
-#endif
-#if INET6
                case AF_INET6:
                        /* total packet length will be computed in ip6_output() */
                        break;
-#endif
                }
        }
 
@@ -900,7 +855,7 @@ fill_icv:
                                error = ENOBUFS;
                                goto fail;
                        }
-                       nn->m_len = siz;
+                       nn->m_len = (int)siz;
                        nn->m_next = NULL;
                        n->m_next = nn;
                        n = nn;
@@ -911,11 +866,10 @@ fill_icv:
 
                /* modify IP header (for ESP header part only) */
                switch (af) {
-       #if INET
                case AF_INET:
                        ip = mtod(m, struct ip *);
                        if (siz < (IP_MAXPACKET - ntohs(ip->ip_len))) {
-                               ip->ip_len = htons(ntohs(ip->ip_len) + siz);
+                               ip->ip_len = htons(ntohs(ip->ip_len) + (u_short)siz);
                        } else {
                                ipseclog((LOG_ERR,
                                    "IPv4 ESP output: size exceeds limit\n"));
@@ -925,12 +879,9 @@ fill_icv:
                                goto fail;
                        }
                        break;
-       #endif
-       #if INET6
                case AF_INET6:
                        /* total packet length will be computed in ip6_output() */
                        break;
-       #endif
                }
        }
 
@@ -941,11 +892,12 @@ fill_icv:
                switch (af) {
                case AF_INET:
                        ip = mtod(m, struct ip *);
-                       udp->uh_ulen = htons(ntohs(ip->ip_len) - (IP_VHL_HL(ip->ip_vhl) << 2));
+                       udp->uh_ulen = htons((u_int16_t)(ntohs(ip->ip_len) - (IP_VHL_HL(ip->ip_vhl) << 2)));
                        break;
                case AF_INET6:
                        ip6 = mtod(m, struct ip6_hdr *);
-                       udp->uh_ulen = htons(plen + siz + extendsiz + esphlen);
+                       VERIFY((plen + siz + extendsiz + esphlen) <= UINT16_MAX);
+                       udp->uh_ulen = htons((u_int16_t)(plen + siz + extendsiz + esphlen));
                        udp->uh_sum = in6_pseudo(&ip6->ip6_src, &ip6->ip6_dst, htonl(ntohs(udp->uh_ulen) + IPPROTO_UDP));
                        m->m_pkthdr.csum_flags = (CSUM_UDPIPV6 | CSUM_ZERO_INVERT);
                        m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
@@ -962,7 +914,7 @@ noantireplay:
                    ntohl(spi), seq,
                    ntohs(th.th_sport), ntohs(th.th_dport),
                    ntohl(th.th_seq), ntohl(th.th_ack),
-                   th.th_flags, inner_payload_len);
+                   inner_payload_len, th.th_flags);
        }
 
        lck_mtx_lock(sadb_mutex);
@@ -979,15 +931,10 @@ noantireplay:
        return 0;
 
 fail:
-#if 1
        KERNEL_DEBUG(DBG_FNC_ESPOUT | DBG_FUNC_END, 7, error, 0, 0, 0);
        return error;
-#else
-       panic("something bad in esp_output");
-#endif
 }
 
-#if INET
 int
 esp4_output(
        struct mbuf *m,
@@ -1003,9 +950,7 @@ esp4_output(
        /* XXX assumes that m->m_next points to payload */
        return esp_output(m, &ip->ip_p, m->m_next, AF_INET, sav);
 }
-#endif /*INET*/
 
-#if INET6
 int
 esp6_output(
        struct mbuf *m,
@@ -1020,4 +965,3 @@ esp6_output(
        }
        return esp_output(m, nexthdrp, md, AF_INET6, sav);
 }
-#endif /*INET6*/