]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/ah_output.c
xnu-3789.1.32.tar.gz
[apple/xnu.git] / bsd / netinet6 / ah_output.c
index 5a4f92cff6438fcd7be1704a104433ec24052420..1e723fa3f7fb767a264ca0157e56ffe228302edf 100644 (file)
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
 /*     $FreeBSD: src/sys/netinet6/ah_output.c,v 1.1.2.3 2001/07/03 11:01:49 ume Exp $  */
 /*     $KAME: ah_output.c,v 1.30 2001/02/21 00:50:53 itojun Exp $      */
 
 #include <net/net_osdep.h>
 
 #if INET
-static struct in_addr *ah4_finaldst __P((struct mbuf *));
+static struct in_addr *ah4_finaldst(struct mbuf *);
 #endif
 
+extern lck_mtx_t *sadb_mutex;
+
 /*
  * compute AH header size.
  * transport mode only.  for tunnel mode, we should implement
  * virtual interface, and control MTU/MSS by the interface MTU.
  */
 size_t
-ah_hdrsiz(isr)
-       struct ipsecrequest *isr;
+ah_hdrsiz(struct ipsecrequest *isr)
 {
-       const struct ah_algorithm *algo;
-       size_t hdrsiz;
 
        /* sanity check */
        if (isr == NULL)
@@ -100,33 +127,46 @@ ah_hdrsiz(isr)
        if (isr->saidx.proto != IPPROTO_AH)
                panic("unsupported mode passed to ah_hdrsiz");
 
-       if (isr->sav == NULL)
-               goto estimate;
-       if (isr->sav->state != SADB_SASTATE_MATURE
-        && isr->sav->state != SADB_SASTATE_DYING)
-               goto estimate;
+#if 0
+       {
 
-       /* we need transport mode AH. */
-       algo = ah_algorithm_lookup(isr->sav->alg_auth);
-       if (!algo)
-               goto estimate;
+               lck_mtx_lock(sadb_mutex);
+               const struct ah_algorithm *algo;
+               size_t hdrsiz;
 
-       /*
-        * XXX
-        * right now we don't calcurate the padding size.  simply
-        * treat the padding size as constant, for simplicity.
-        *
-        * XXX variable size padding support
-        */
-       hdrsiz = (((*algo->sumsiz)(isr->sav) + 3) & ~(4 - 1));
-       if (isr->sav->flags & SADB_X_EXT_OLD)
-               hdrsiz += sizeof(struct ah);
-       else
-               hdrsiz += sizeof(struct newah);
+               /*%%%%% this needs to change - no sav in ipsecrequest any more */
+               if (isr->sav == NULL)
+                       goto estimate;
+               if (isr->sav->state != SADB_SASTATE_MATURE
+                && isr->sav->state != SADB_SASTATE_DYING)
+                       goto estimate;
+       
+               /* we need transport mode AH. */
+               algo = ah_algorithm_lookup(isr->sav->alg_auth);
+               if (!algo)
+                       goto estimate;
+       
+               /*
+                * XXX
+                * right now we don't calcurate the padding size.  simply
+                * treat the padding size as constant, for simplicity.
+                *
+                * XXX variable size padding support
+                */
+               hdrsiz = (((*algo->sumsiz)(isr->sav) + 3) & ~(4 - 1));
+               if (isr->sav->flags & SADB_X_EXT_OLD)
+                       hdrsiz += sizeof(struct ah);
+               else
+                       hdrsiz += sizeof(struct newah);
+       
+               lck_mtx_unlock(sadb_mutex);
+               return hdrsiz;
+       }
 
-       return hdrsiz;
+estimate:
+#endif
 
-    estimate:
+    //lck_mtx_unlock(sadb_mutex);
        /* ASSUMING:
         *      sizeof(struct newah) > sizeof(struct ah).
         *      16 = (16 + 3) & ~(4 - 1).
@@ -143,11 +183,8 @@ ah_hdrsiz(isr)
  * the function does not modify m.
  */
 int
-ah4_output(m, isr)
-       struct mbuf *m;
-       struct ipsecrequest *isr;
+ah4_output(struct mbuf *m, struct secasvar *sav)
 {
-       struct secasvar *sav = isr->sav;
        const struct ah_algorithm *algo;
        u_int32_t spi;
        u_char *ahdrpos;
@@ -156,21 +193,19 @@ ah4_output(m, isr)
        size_t plen = 0;        /*AH payload size in bytes*/
        size_t ahlen = 0;       /*plen + sizeof(ah)*/
        struct ip *ip;
-       struct in_addr dst;
+       struct in_addr dst = { 0 };
        struct in_addr *finaldst;
        int error;
 
        /* sanity checks */
        if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
-               struct ip *ip;
-
                ip = mtod(m, struct ip *);
                ipseclog((LOG_DEBUG, "ah4_output: internal error: "
                        "sav->replay is null: %x->%x, SPI=%u\n",
                        (u_int32_t)ntohl(ip->ip_src.s_addr),
                        (u_int32_t)ntohl(ip->ip_dst.s_addr),
                        (u_int32_t)ntohl(sav->spi)));
-               ipsecstat.out_inval++;
+               IPSEC_STAT_INCREMENT(ipsecstat.out_inval);
                m_freem(m);
                return EINVAL;
        }
@@ -179,7 +214,7 @@ ah4_output(m, isr)
        if (!algo) {
                ipseclog((LOG_ERR, "ah4_output: unsupported algorithm: "
                    "SPI=%u\n", (u_int32_t)ntohl(sav->spi)));
-               ipsecstat.out_inval++;
+               IPSEC_STAT_INCREMENT(ipsecstat.out_inval);
                m_freem(m);
                return EINVAL;
        }
@@ -239,7 +274,7 @@ ah4_output(m, isr)
        if (sav->flags & SADB_X_EXT_OLD) {
                struct ah *ahdr;
 
-               ahdr = (struct ah *)ahdrpos;
+               ahdr = (struct ah *)(void *)ahdrpos;
                ahsumpos = (u_char *)(ahdr + 1);
                ahdr->ah_len = plen >> 2;
                ahdr->ah_nxt = ip->ip_p;
@@ -249,7 +284,7 @@ ah4_output(m, isr)
        } else {
                struct newah *ahdr;
 
-               ahdr = (struct newah *)ahdrpos;
+               ahdr = (struct newah *)(void *)ahdrpos;
                ahsumpos = (u_char *)(ahdr + 1);
                ahdr->ah_len = (plen >> 2) + 1; /* plus one for seq# */
                ahdr->ah_nxt = ip->ip_p;
@@ -261,12 +296,14 @@ ah4_output(m, isr)
                                ipseclog((LOG_WARNING,
                                    "replay counter overflowed. %s\n",
                                    ipsec_logsastr(sav)));
-                               ipsecstat.out_inval++;
+                               IPSEC_STAT_INCREMENT(ipsecstat.out_inval);
                                m_freem(m);
                                return EINVAL;
                        }
                }
+               lck_mtx_lock(sadb_mutex);
                sav->replay->count++;
+               lck_mtx_unlock(sadb_mutex);
                /*
                 * XXX sequence number must not be cycled, if the SA is
                 * installed by IKE daemon.
@@ -283,7 +320,7 @@ ah4_output(m, isr)
                ip->ip_len = htons(ntohs(ip->ip_len) + ahlen);
        else {
                ipseclog((LOG_ERR, "IPv4 AH output: size exceeds limit\n"));
-               ipsecstat.out_inval++;
+               IPSEC_STAT_INCREMENT(ipsecstat.out_inval);
                m_freem(m);
                return EMSGSIZE;
        }
@@ -311,7 +348,7 @@ ah4_output(m, isr)
                    "error after ah4_calccksum, called from ah4_output"));
                m_freem(m);
                m = NULL;
-               ipsecstat.out_inval++;
+               IPSEC_STAT_INCREMENT(ipsecstat.out_inval);
                return error;
        }
 
@@ -319,8 +356,10 @@ ah4_output(m, isr)
                ip = mtod(m, struct ip *);      /*just to make sure*/
                ip->ip_dst.s_addr = dst.s_addr;
        }
+       lck_mtx_lock(sadb_stat_mutex);
        ipsecstat.out_success++;
        ipsecstat.out_ahhist[sav->alg_auth]++;
+       lck_mtx_unlock(sadb_stat_mutex);
        key_sa_recordxfer(sav, m);
 
        return 0;
@@ -329,8 +368,7 @@ ah4_output(m, isr)
 
 /* Calculate AH length */
 int
-ah_hdrlen(sav)
-       struct secasvar *sav;
+ah_hdrlen(struct secasvar *sav)
 {
        const struct ah_algorithm *algo;
        int plen, ahlen;
@@ -356,15 +394,11 @@ ah_hdrlen(sav)
  * Fill in the Authentication Header and calculate checksum.
  */
 int
-ah6_output(m, nexthdrp, md, isr)
-       struct mbuf *m;
-       u_char *nexthdrp;
-       struct mbuf *md;
-       struct ipsecrequest *isr;
+ah6_output(struct mbuf *m, u_char *nexthdrp, struct mbuf *md,
+          struct secasvar *sav)
 {
        struct mbuf *mprev;
        struct mbuf *mah;
-       struct secasvar *sav = isr->sav;
        const struct ah_algorithm *algo;
        u_int32_t spi;
        u_char *ahsumpos = NULL;
@@ -421,9 +455,9 @@ ah6_output(m, nexthdrp, md, isr)
 
        if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
                ipseclog((LOG_DEBUG, "ah6_output: internal error: "
-                       "sav->replay is null: SPI=%u\n",
-                       (u_int32_t)ntohl(sav->spi)));
-               ipsec6stat.out_inval++;
+                         "sav->replay is null: SPI=%u\n",
+                         (u_int32_t)ntohl(sav->spi)));
+               IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
                m_freem(m);
                return EINVAL;
        }
@@ -432,7 +466,7 @@ ah6_output(m, nexthdrp, md, isr)
        if (!algo) {
                ipseclog((LOG_ERR, "ah6_output: unsupported algorithm: "
                    "SPI=%u\n", (u_int32_t)ntohl(sav->spi)));
-               ipsec6stat.out_inval++;
+               IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
                m_freem(m);
                return EINVAL;
        }
@@ -466,14 +500,16 @@ ah6_output(m, nexthdrp, md, isr)
                        if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
                                /* XXX Is it noisy ? */
                                ipseclog((LOG_WARNING,
-                                   "replay counter overflowed. %s\n",
+                                    "replay counter overflowed. %s\n",
                                    ipsec_logsastr(sav)));
-                               ipsec6stat.out_inval++;
+                               IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
                                m_freem(m);
                                return EINVAL;
                        }
                }
+               lck_mtx_lock(sadb_mutex);
                sav->replay->count++;
+               lck_mtx_unlock(sadb_mutex);
                /*
                 * XXX sequence number must not be cycled, if the SA is
                 * installed by IKE daemon.
@@ -488,13 +524,13 @@ ah6_output(m, nexthdrp, md, isr)
         */
        error = ah6_calccksum(m, (caddr_t)ahsumpos, plen, algo, sav);
        if (error) {
-               ipsec6stat.out_inval++;
+               IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
                m_freem(m);
        } else {
-               ipsec6stat.out_success++;
+               IPSEC_STAT_INCREMENT(ipsec6stat.out_success);
                key_sa_recordxfer(sav, m);
        }
-       ipsec6stat.out_ahhist[sav->alg_auth]++;
+       IPSEC_STAT_INCREMENT(ipsec6stat.out_ahhist[sav->alg_auth]);
 
        return(error);
 }
@@ -510,8 +546,7 @@ ah6_output(m, nexthdrp, md, isr)
  * The mbuf must be pulled up toward, at least, ip option part.
  */
 static struct in_addr *
-ah4_finaldst(m)
-       struct mbuf *m;
+ah4_finaldst(struct mbuf *m)
 {
        struct ip *ip;
        int optlen;
@@ -574,7 +609,7 @@ ah4_finaldst(m)
                                return NULL;
                        }
                        i += q[i + IPOPT_OLEN] - sizeof(struct in_addr);
-                       return (struct in_addr *)(q + i);
+                       return (struct in_addr *)(void *)(q + i);
                default:
                        if (q[i + IPOPT_OLEN] < 2 ||
                            optlen - i < q[i + IPOPT_OLEN]) {