darwin-xnu/bsd/netinet6/ipsec.c
<<
>>
Prefs
   1/*      $FreeBSD: src/sys/netinet6/ipsec.c,v 1.3.2.7 2001/07/19 06:37:23 kris Exp $     */
   2/*      $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
   3
   4/*
   5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
   6 * All rights reserved.
   7 *
   8 * Redistribution and use in source and binary forms, with or without
   9 * modification, are permitted provided that the following conditions
  10 * are met:
  11 * 1. Redistributions of source code must retain the above copyright
  12 *    notice, this list of conditions and the following disclaimer.
  13 * 2. Redistributions in binary form must reproduce the above copyright
  14 *    notice, this list of conditions and the following disclaimer in the
  15 *    documentation and/or other materials provided with the distribution.
  16 * 3. Neither the name of the project nor the names of its contributors
  17 *    may be used to endorse or promote products derived from this software
  18 *    without specific prior written permission.
  19 *
  20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30 * SUCH DAMAGE.
  31 */
  32
  33/*
  34 * IPsec controller part.
  35 */
  36
  37#include <sys/param.h>
  38#include <sys/systm.h>
  39#include <sys/malloc.h>
  40#include <sys/mbuf.h>
  41#include <sys/domain.h>
  42#include <sys/protosw.h>
  43#include <sys/socket.h>
  44#include <sys/socketvar.h>
  45#include <sys/errno.h>
  46#include <sys/time.h>
  47#include <sys/kernel.h>
  48#include <sys/syslog.h>
  49#include <sys/sysctl.h>
  50#include <kern/locks.h>
  51#include <sys/kauth.h>
  52
  53#include <net/if.h>
  54#include <net/route.h>
  55
  56#include <netinet/in.h>
  57#include <netinet/in_systm.h>
  58#include <netinet/ip.h>
  59#include <netinet/ip_var.h>
  60#include <netinet/in_var.h>
  61#include <netinet/udp.h>
  62#include <netinet/udp_var.h>
  63#include <netinet/ip_ecn.h>
  64#if INET6
  65#include <netinet6/ip6_ecn.h>
  66#endif
  67#include <netinet/tcp.h>
  68#include <netinet/udp.h>
  69
  70#include <netinet/ip6.h>
  71#if INET6
  72#include <netinet6/ip6_var.h>
  73#endif
  74#include <netinet/in_pcb.h>
  75#if INET6
  76#include <netinet/icmp6.h>
  77#endif
  78
  79#include <netinet6/ipsec.h>
  80#if INET6
  81#include <netinet6/ipsec6.h>
  82#endif
  83#include <netinet6/ah.h>
  84#if INET6
  85#include <netinet6/ah6.h>
  86#endif
  87#if IPSEC_ESP
  88#include <netinet6/esp.h>
  89#if INET6
  90#include <netinet6/esp6.h>
  91#endif
  92#endif
  93#include <netinet6/ipcomp.h>
  94#if INET6
  95#include <netinet6/ipcomp6.h>
  96#endif
  97#include <netkey/key.h>
  98#include <netkey/keydb.h>
  99#include <netkey/key_debug.h>
 100
 101#include <net/net_osdep.h>
 102
 103#if IPSEC_DEBUG
 104int ipsec_debug = 1;
 105#else
 106int ipsec_debug = 0;
 107#endif
 108
 109#include <sys/kdebug.h>
 110#define DBG_LAYER_BEG                   NETDBG_CODE(DBG_NETIPSEC, 1)
 111#define DBG_LAYER_END                   NETDBG_CODE(DBG_NETIPSEC, 3)
 112#define DBG_FNC_GETPOL_SOCK             NETDBG_CODE(DBG_NETIPSEC, (1 << 8))
 113#define DBG_FNC_GETPOL_ADDR             NETDBG_CODE(DBG_NETIPSEC, (2 << 8))
 114#define DBG_FNC_IPSEC_OUT               NETDBG_CODE(DBG_NETIPSEC, (3 << 8))
 115
 116extern lck_mtx_t *sadb_mutex;
 117extern lck_mtx_t *ip6_mutex;
 118
 119struct ipsecstat ipsecstat;
 120int ip4_ah_cleartos = 1;
 121int ip4_ah_offsetmask = 0;      /* maybe IP_DF? */
 122int ip4_ipsec_dfbit = 0;        /* DF bit on encap. 0: clear 1: set 2: copy */
 123int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
 124int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
 125int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
 126int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
 127struct secpolicy ip4_def_policy;
 128int ip4_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
 129int ip4_esp_randpad = -1;
 130int     esp_udp_encap_port = 0;
 131static int sysctl_def_policy SYSCTL_HANDLER_ARGS;
 132extern u_int32_t natt_now;
 133
 134SYSCTL_DECL(_net_inet_ipsec);
 135#if INET6
 136SYSCTL_DECL(_net_inet6_ipsec6);
 137#endif
 138/* net.inet.ipsec */
 139SYSCTL_STRUCT(_net_inet_ipsec, IPSECCTL_STATS,
 140        stats, CTLFLAG_RD,      &ipsecstat,     ipsecstat, "");
 141SYSCTL_PROC(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, CTLTYPE_INT|CTLFLAG_RW,
 142        &ip4_def_policy.policy, 0, &sysctl_def_policy, "I", "");
 143SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
 144        CTLFLAG_RW, &ip4_esp_trans_deflev,      0, "");
 145SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
 146        CTLFLAG_RW, &ip4_esp_net_deflev,        0, "");
 147SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
 148        CTLFLAG_RW, &ip4_ah_trans_deflev,       0, "");
 149SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
 150        CTLFLAG_RW, &ip4_ah_net_deflev, 0, "");
 151SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
 152        ah_cleartos, CTLFLAG_RW,        &ip4_ah_cleartos,       0, "");
 153SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
 154        ah_offsetmask, CTLFLAG_RW,      &ip4_ah_offsetmask,     0, "");
 155SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
 156        dfbit, CTLFLAG_RW,      &ip4_ipsec_dfbit,       0, "");
 157SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
 158        ecn, CTLFLAG_RW,        &ip4_ipsec_ecn, 0, "");
 159SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
 160        debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
 161SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
 162        esp_randpad, CTLFLAG_RW,        &ip4_esp_randpad,       0, "");
 163
 164/* for performance, we bypass ipsec until a security policy is set */
 165int ipsec_bypass = 1;
 166SYSCTL_INT(_net_inet_ipsec, OID_AUTO, bypass, CTLFLAG_RD, &ipsec_bypass,0, "");
 167
 168/*
 169 * NAT Traversal requires a UDP port for encapsulation,
 170 * esp_udp_encap_port controls which port is used. Racoon
 171 * must set this port to the port racoon is using locally
 172 * for nat traversal.
 173 */
 174SYSCTL_INT(_net_inet_ipsec, OID_AUTO, esp_port,
 175                   CTLFLAG_RW, &esp_udp_encap_port, 0, "");
 176
 177#if INET6
 178struct ipsecstat ipsec6stat;
 179int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
 180int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
 181int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
 182int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
 183struct secpolicy ip6_def_policy;
 184int ip6_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
 185int ip6_esp_randpad = -1;
 186
 187/* net.inet6.ipsec6 */
 188SYSCTL_STRUCT(_net_inet6_ipsec6, IPSECCTL_STATS,
 189        stats, CTLFLAG_RD, &ipsec6stat, ipsecstat, "");
 190SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
 191        def_policy, CTLFLAG_RW, &ip6_def_policy.policy, 0, "");
 192SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
 193        CTLFLAG_RW, &ip6_esp_trans_deflev,      0, "");
 194SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
 195        CTLFLAG_RW, &ip6_esp_net_deflev,        0, "");
 196SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
 197        CTLFLAG_RW, &ip6_ah_trans_deflev,       0, "");
 198SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
 199        CTLFLAG_RW, &ip6_ah_net_deflev, 0, "");
 200SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
 201        ecn, CTLFLAG_RW,        &ip6_ipsec_ecn, 0, "");
 202SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
 203        debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
 204SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
 205        esp_randpad, CTLFLAG_RW,        &ip6_esp_randpad,       0, "");
 206#endif /* INET6 */
 207
 208static int ipsec_setspidx_mbuf(struct secpolicyindex *, u_int, u_int,
 209        struct mbuf *, int);
 210static int ipsec4_setspidx_inpcb(struct mbuf *, struct inpcb *pcb);
 211#if INET6
 212static int ipsec6_setspidx_in6pcb(struct mbuf *, struct in6pcb *pcb);
 213#endif
 214static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int);
 215static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
 216static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
 217#if INET6
 218static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
 219static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
 220#endif
 221static struct inpcbpolicy *ipsec_newpcbpolicy(void);
 222static void ipsec_delpcbpolicy(struct inpcbpolicy *);
 223static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
 224static int ipsec_set_policy(struct secpolicy **pcb_sp,
 225        int optname, caddr_t request, size_t len, int priv);
 226static int ipsec_get_policy(struct secpolicy *pcb_sp, struct mbuf **mp);
 227static void vshiftl(unsigned char *, int, int);
 228static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
 229static size_t ipsec_hdrsiz(struct secpolicy *);
 230#if INET
 231static struct mbuf *ipsec4_splithdr(struct mbuf *);
 232#endif
 233#if INET6
 234static struct mbuf *ipsec6_splithdr(struct mbuf *);
 235#endif
 236#if INET
 237static int ipsec4_encapsulate(struct mbuf *, struct secasvar *);
 238#endif
 239#if INET6
 240static int ipsec6_encapsulate(struct mbuf *, struct secasvar *);
 241#endif
 242static struct mbuf *ipsec_addaux(struct mbuf *);
 243static struct mbuf *ipsec_findaux(struct mbuf *);
 244static void ipsec_optaux(struct mbuf *, struct mbuf *);
 245void ipsec_send_natt_keepalive(struct secasvar *sav);
 246
 247static int
 248sysctl_def_policy SYSCTL_HANDLER_ARGS
 249{
 250        int old_policy = ip4_def_policy.policy;
 251        int error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
 252
 253        if (ip4_def_policy.policy != IPSEC_POLICY_NONE &&
 254                ip4_def_policy.policy != IPSEC_POLICY_DISCARD) {
 255                ip4_def_policy.policy = old_policy;
 256                return EINVAL;
 257        }
 258
 259        /* Turn off the bypass if the default security policy changes */
 260        if (ipsec_bypass != 0 && ip4_def_policy.policy != IPSEC_POLICY_NONE)
 261                ipsec_bypass = 0;
 262
 263        return error;
 264}
 265
 266/*
 267 * For OUTBOUND packet having a socket. Searching SPD for packet,
 268 * and return a pointer to SP.
 269 * OUT: NULL:   no apropreate SP found, the following value is set to error.
 270 *              0       : bypass
 271 *              EACCES  : discard packet.
 272 *              ENOENT  : ipsec_acquire() in progress, maybe.
 273 *              others  : error occurred.
 274 *      others: a pointer to SP
 275 *
 276 * NOTE: IPv6 mapped adddress concern is implemented here.
 277 */
 278struct secpolicy *
 279ipsec4_getpolicybysock(m, dir, so, error)
 280        struct mbuf *m;
 281        u_int dir;
 282        struct socket *so;
 283        int *error;
 284{
 285        struct inpcbpolicy *pcbsp = NULL;
 286        struct secpolicy *currsp = NULL;        /* policy on socket */
 287        struct secpolicy *kernsp = NULL;        /* policy on kernel */
 288
 289        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
 290        /* sanity check */
 291        if (m == NULL || so == NULL || error == NULL)
 292                panic("ipsec4_getpolicybysock: NULL pointer was passed.\n");
 293        
 294        if (so->so_pcb == NULL) {
 295                printf("ipsec4_getpolicybysock: so->so_pcb == NULL\n");
 296                return ipsec4_getpolicybyaddr(m, dir, 0, error);
 297        }
 298        
 299        switch (so->so_proto->pr_domain->dom_family) {
 300        case AF_INET:
 301                pcbsp = sotoinpcb(so)->inp_sp;
 302                break;
 303#if INET6
 304        case AF_INET6:
 305                pcbsp = sotoin6pcb(so)->in6p_sp;
 306                break;
 307#endif
 308        }
 309        
 310        if (!pcbsp){
 311                /* Socket has not specified an IPSEC policy */
 312                return ipsec4_getpolicybyaddr(m, dir, 0, error);
 313        }
 314
 315        KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_START, 0,0,0,0,0);
 316
 317        switch (so->so_proto->pr_domain->dom_family) {
 318        case AF_INET:
 319                /* set spidx in pcb */
 320                *error = ipsec4_setspidx_inpcb(m, sotoinpcb(so));
 321                break;
 322#if INET6
 323        case AF_INET6:
 324                /* set spidx in pcb */
 325                *error = ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
 326                break;
 327#endif
 328        default:
 329                panic("ipsec4_getpolicybysock: unsupported address family\n");
 330        }
 331        if (*error) {
 332                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 1,*error,0,0,0);
 333                return NULL;
 334        }
 335
 336        /* sanity check */
 337        if (pcbsp == NULL)
 338                panic("ipsec4_getpolicybysock: pcbsp is NULL.\n");
 339
 340        switch (dir) {
 341        case IPSEC_DIR_INBOUND:
 342                currsp = pcbsp->sp_in;
 343                break;
 344        case IPSEC_DIR_OUTBOUND:
 345                currsp = pcbsp->sp_out;
 346                break;
 347        default:
 348                panic("ipsec4_getpolicybysock: illegal direction.\n");
 349        }
 350
 351        /* sanity check */
 352        if (currsp == NULL)
 353                panic("ipsec4_getpolicybysock: currsp is NULL.\n");
 354
 355        /* when privilieged socket */
 356        if (pcbsp->priv) {
 357                switch (currsp->policy) {
 358                case IPSEC_POLICY_BYPASS:
 359                        currsp->refcnt++;
 360                        *error = 0;
 361                        KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 2,*error,0,0,0);
 362                        return currsp;
 363
 364                case IPSEC_POLICY_ENTRUST:
 365                        /* look for a policy in SPD */
 366                        kernsp = key_allocsp(&currsp->spidx, dir);
 367
 368                        /* SP found */
 369                        if (kernsp != NULL) {
 370                                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 371                                        printf("DP ipsec4_getpolicybysock called "
 372                                               "to allocate SP:%p\n", kernsp));
 373                                *error = 0;
 374                                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 3,*error,0,0,0);
 375                                return kernsp;
 376                        }
 377
 378                        /* no SP found */
 379                        if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
 380                         && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
 381                                ipseclog((LOG_INFO,
 382                                    "fixed system default policy: %d->%d\n",
 383                                    ip4_def_policy.policy, IPSEC_POLICY_NONE));
 384                                ip4_def_policy.policy = IPSEC_POLICY_NONE;
 385                        }
 386                        ip4_def_policy.refcnt++;
 387                        *error = 0;
 388                        KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 4,*error,0,0,0);
 389                        return &ip4_def_policy;
 390                        
 391                case IPSEC_POLICY_IPSEC:
 392                        currsp->refcnt++;
 393                        *error = 0;
 394                        KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 5,*error,0,0,0);
 395                        return currsp;
 396
 397                default:
 398                        ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
 399                              "Invalid policy for PCB %d\n", currsp->policy));
 400                        *error = EINVAL;
 401                        KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 6,*error,0,0,0);
 402                        return NULL;
 403                }
 404                /* NOTREACHED */
 405        }
 406
 407        /* when non-privilieged socket */
 408        /* look for a policy in SPD */
 409        kernsp = key_allocsp(&currsp->spidx, dir);
 410
 411        /* SP found */
 412        if (kernsp != NULL) {
 413                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 414                        printf("DP ipsec4_getpolicybysock called "
 415                               "to allocate SP:%p\n", kernsp));
 416                *error = 0;
 417                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 7,*error,0,0,0);
 418                return kernsp;
 419        }
 420
 421        /* no SP found */
 422        switch (currsp->policy) {
 423        case IPSEC_POLICY_BYPASS:
 424                ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
 425                       "Illegal policy for non-priviliged defined %d\n",
 426                        currsp->policy));
 427                *error = EINVAL;
 428                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 8,*error,0,0,0);
 429                return NULL;
 430
 431        case IPSEC_POLICY_ENTRUST:
 432                if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
 433                 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
 434                        ipseclog((LOG_INFO,
 435                            "fixed system default policy: %d->%d\n",
 436                            ip4_def_policy.policy, IPSEC_POLICY_NONE));
 437                        ip4_def_policy.policy = IPSEC_POLICY_NONE;
 438                }
 439                ip4_def_policy.refcnt++;
 440                *error = 0;
 441                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 9,*error,0,0,0);
 442                return &ip4_def_policy;
 443
 444        case IPSEC_POLICY_IPSEC:
 445                currsp->refcnt++;
 446                *error = 0;
 447                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 10,*error,0,0,0);
 448                return currsp;
 449
 450        default:
 451                ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
 452                   "Invalid policy for PCB %d\n", currsp->policy));
 453                *error = EINVAL;
 454                KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 11,*error,0,0,0);
 455                return NULL;
 456        }
 457        /* NOTREACHED */
 458}
 459
 460/*
 461 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
 462 * and return a pointer to SP.
 463 * OUT: positive: a pointer to the entry for security policy leaf matched.
 464 *      NULL:   no apropreate SP found, the following value is set to error.
 465 *              0       : bypass
 466 *              EACCES  : discard packet.
 467 *              ENOENT  : ipsec_acquire() in progress, maybe.
 468 *              others  : error occurred.
 469 */
 470struct secpolicy *
 471ipsec4_getpolicybyaddr(m, dir, flag, error)
 472        struct mbuf *m;
 473        u_int dir;
 474        int flag;
 475        int *error;
 476{
 477        struct secpolicy *sp = NULL;
 478
 479        if (ipsec_bypass != 0)
 480                return 0;
 481
 482        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
 483
 484        /* sanity check */
 485        if (m == NULL || error == NULL)
 486                panic("ipsec4_getpolicybyaddr: NULL pointer was passed.\n");
 487
 488    {
 489        struct secpolicyindex spidx;
 490
 491        KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_START, 0,0,0,0,0);
 492        bzero(&spidx, sizeof(spidx));
 493
 494        /* make a index to look for a policy */
 495        *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET, m,
 496            (flag & IP_FORWARDING) ? 0 : 1);
 497
 498        if (*error != 0) {
 499                KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 1,*error,0,0,0);
 500                return NULL;
 501        }
 502
 503        sp = key_allocsp(&spidx, dir);
 504    }
 505
 506        /* SP found */
 507        if (sp != NULL) {
 508                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 509                        printf("DP ipsec4_getpolicybyaddr called "
 510                               "to allocate SP:%p\n", sp));
 511                *error = 0;
 512                KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 2,*error,0,0,0);
 513                return sp;
 514        }
 515
 516        /* no SP found */
 517        if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
 518         && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
 519                ipseclog((LOG_INFO, "fixed system default policy:%d->%d\n",
 520                        ip4_def_policy.policy,
 521                        IPSEC_POLICY_NONE));
 522                ip4_def_policy.policy = IPSEC_POLICY_NONE;
 523        }
 524        ip4_def_policy.refcnt++;
 525        *error = 0;
 526        KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 3,*error,0,0,0);
 527        return &ip4_def_policy;
 528}
 529
 530#if INET6
 531/*
 532 * For OUTBOUND packet having a socket. Searching SPD for packet,
 533 * and return a pointer to SP.
 534 * OUT: NULL:   no apropreate SP found, the following value is set to error.
 535 *              0       : bypass
 536 *              EACCES  : discard packet.
 537 *              ENOENT  : ipsec_acquire() in progress, maybe.
 538 *              others  : error occurred.
 539 *      others: a pointer to SP
 540 */
 541struct secpolicy *
 542ipsec6_getpolicybysock(m, dir, so, error)
 543        struct mbuf *m;
 544        u_int dir;
 545        struct socket *so;
 546        int *error;
 547{
 548        struct inpcbpolicy *pcbsp = NULL;
 549        struct secpolicy *currsp = NULL;        /* policy on socket */
 550        struct secpolicy *kernsp = NULL;        /* policy on kernel */
 551
 552        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
 553
 554        /* sanity check */
 555        if (m == NULL || so == NULL || error == NULL)
 556                panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
 557
 558#if DIAGNOSTIC
 559        if (so->so_proto->pr_domain->dom_family != AF_INET6)
 560                panic("ipsec6_getpolicybysock: socket domain != inet6\n");
 561#endif
 562
 563        pcbsp = sotoin6pcb(so)->in6p_sp;
 564        
 565        if (!pcbsp){
 566                return ipsec6_getpolicybyaddr(m, dir, 0, error);
 567        }
 568
 569        /* set spidx in pcb */
 570        ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
 571
 572        /* sanity check */
 573        if (pcbsp == NULL)
 574                panic("ipsec6_getpolicybysock: pcbsp is NULL.\n");
 575
 576        switch (dir) {
 577        case IPSEC_DIR_INBOUND:
 578                currsp = pcbsp->sp_in;
 579                break;
 580        case IPSEC_DIR_OUTBOUND:
 581                currsp = pcbsp->sp_out;
 582                break;
 583        default:
 584                panic("ipsec6_getpolicybysock: illegal direction.\n");
 585        }
 586
 587        /* sanity check */
 588        if (currsp == NULL)
 589                panic("ipsec6_getpolicybysock: currsp is NULL.\n");
 590
 591        /* when privilieged socket */
 592        if (pcbsp->priv) {
 593                switch (currsp->policy) {
 594                case IPSEC_POLICY_BYPASS:
 595                        currsp->refcnt++;
 596                        *error = 0;
 597                        return currsp;
 598
 599                case IPSEC_POLICY_ENTRUST:
 600                        /* look for a policy in SPD */
 601                        kernsp = key_allocsp(&currsp->spidx, dir);
 602
 603                        /* SP found */
 604                        if (kernsp != NULL) {
 605                                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 606                                        printf("DP ipsec6_getpolicybysock called "
 607                                               "to allocate SP:%p\n", kernsp));
 608                                *error = 0;
 609                                return kernsp;
 610                        }
 611
 612                        /* no SP found */
 613                        if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
 614                         && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
 615                                ipseclog((LOG_INFO,
 616                                    "fixed system default policy: %d->%d\n",
 617                                    ip6_def_policy.policy, IPSEC_POLICY_NONE));
 618                                ip6_def_policy.policy = IPSEC_POLICY_NONE;
 619                        }
 620                        ip6_def_policy.refcnt++;
 621                        *error = 0;
 622                        return &ip6_def_policy;
 623                        
 624                case IPSEC_POLICY_IPSEC:
 625                        currsp->refcnt++;
 626                        *error = 0;
 627                        return currsp;
 628
 629                default:
 630                        ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
 631                            "Invalid policy for PCB %d\n", currsp->policy));
 632                        *error = EINVAL;
 633                        return NULL;
 634                }
 635                /* NOTREACHED */
 636        }
 637
 638        /* when non-privilieged socket */
 639        /* look for a policy in SPD */
 640        kernsp = key_allocsp(&currsp->spidx, dir);
 641
 642        /* SP found */
 643        if (kernsp != NULL) {
 644                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 645                        printf("DP ipsec6_getpolicybysock called "
 646                               "to allocate SP:%p\n", kernsp));
 647                *error = 0;
 648                return kernsp;
 649        }
 650
 651        /* no SP found */
 652        switch (currsp->policy) {
 653        case IPSEC_POLICY_BYPASS:
 654                ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
 655                    "Illegal policy for non-priviliged defined %d\n",
 656                    currsp->policy));
 657                *error = EINVAL;
 658                return NULL;
 659
 660        case IPSEC_POLICY_ENTRUST:
 661                if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
 662                 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
 663                        ipseclog((LOG_INFO,
 664                            "fixed system default policy: %d->%d\n",
 665                            ip6_def_policy.policy, IPSEC_POLICY_NONE));
 666                        ip6_def_policy.policy = IPSEC_POLICY_NONE;
 667                }
 668                ip6_def_policy.refcnt++;
 669                *error = 0;
 670                return &ip6_def_policy;
 671
 672        case IPSEC_POLICY_IPSEC:
 673                currsp->refcnt++;
 674                *error = 0;
 675                return currsp;
 676
 677        default:
 678                ipseclog((LOG_ERR,
 679                    "ipsec6_policybysock: Invalid policy for PCB %d\n",
 680                    currsp->policy));
 681                *error = EINVAL;
 682                return NULL;
 683        }
 684        /* NOTREACHED */
 685}
 686
 687/*
 688 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
 689 * and return a pointer to SP.
 690 * `flag' means that packet is to be forwarded whether or not.
 691 *      flag = 1: forwad
 692 * OUT: positive: a pointer to the entry for security policy leaf matched.
 693 *      NULL:   no apropreate SP found, the following value is set to error.
 694 *              0       : bypass
 695 *              EACCES  : discard packet.
 696 *              ENOENT  : ipsec_acquire() in progress, maybe.
 697 *              others  : error occurred.
 698 */
 699#ifndef IP_FORWARDING
 700#define IP_FORWARDING 1
 701#endif
 702
 703struct secpolicy *
 704ipsec6_getpolicybyaddr(m, dir, flag, error)
 705        struct mbuf *m;
 706        u_int dir;
 707        int flag;
 708        int *error;
 709{
 710        struct secpolicy *sp = NULL;
 711
 712        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
 713
 714        /* sanity check */
 715        if (m == NULL || error == NULL)
 716                panic("ipsec6_getpolicybyaddr: NULL pointer was passed.\n");
 717
 718    {
 719        struct secpolicyindex spidx;
 720
 721        bzero(&spidx, sizeof(spidx));
 722
 723        /* make a index to look for a policy */
 724        *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET6, m,
 725            (flag & IP_FORWARDING) ? 0 : 1);
 726
 727        if (*error != 0)
 728                return NULL;
 729
 730        sp = key_allocsp(&spidx, dir);
 731    }
 732
 733        /* SP found */
 734        if (sp != NULL) {
 735                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 736                        printf("DP ipsec6_getpolicybyaddr called "
 737                               "to allocate SP:%p\n", sp));
 738                *error = 0;
 739                return sp;
 740        }
 741
 742        /* no SP found */
 743        if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
 744         && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
 745                ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
 746                    ip6_def_policy.policy, IPSEC_POLICY_NONE));
 747                ip6_def_policy.policy = IPSEC_POLICY_NONE;
 748        }
 749        ip6_def_policy.refcnt++;
 750        *error = 0;
 751        return &ip6_def_policy;
 752}
 753#endif /* INET6 */
 754
 755/*
 756 * set IP address into spidx from mbuf.
 757 * When Forwarding packet and ICMP echo reply, this function is used.
 758 *
 759 * IN:  get the followings from mbuf.
 760 *      protocol family, src, dst, next protocol
 761 * OUT:
 762 *      0:      success.
 763 *      other:  failure, and set errno.
 764 */
 765int
 766ipsec_setspidx_mbuf(spidx, dir, family, m, needport)
 767        struct secpolicyindex *spidx;
 768        u_int dir, family;
 769        struct mbuf *m;
 770        int needport;
 771{
 772        int error;
 773
 774        /* sanity check */
 775        if (spidx == NULL || m == NULL)
 776                panic("ipsec_setspidx_mbuf: NULL pointer was passed.\n");
 777
 778        bzero(spidx, sizeof(*spidx));
 779
 780        error = ipsec_setspidx(m, spidx, needport);
 781        if (error)
 782                goto bad;
 783        spidx->dir = dir;
 784
 785        return 0;
 786
 787    bad:
 788        /* XXX initialize */
 789        bzero(spidx, sizeof(*spidx));
 790        return EINVAL;
 791}
 792
 793static int
 794ipsec4_setspidx_inpcb(m, pcb)
 795        struct mbuf *m;
 796        struct inpcb *pcb;
 797{
 798        struct secpolicyindex *spidx;
 799        int error;
 800
 801        if (ipsec_bypass != 0)
 802                return 0;
 803
 804        /* sanity check */
 805        if (pcb == NULL)
 806                panic("ipsec4_setspidx_inpcb: no PCB found.\n");
 807        if (pcb->inp_sp == NULL)
 808                panic("ipsec4_setspidx_inpcb: no inp_sp found.\n");
 809        if (pcb->inp_sp->sp_out == NULL || pcb->inp_sp->sp_in == NULL)
 810                panic("ipsec4_setspidx_inpcb: no sp_in/out found.\n");
 811
 812        bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
 813        bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
 814
 815        spidx = &pcb->inp_sp->sp_in->spidx;
 816        error = ipsec_setspidx(m, spidx, 1);
 817        if (error)
 818                goto bad;
 819        spidx->dir = IPSEC_DIR_INBOUND;
 820
 821        spidx = &pcb->inp_sp->sp_out->spidx;
 822        error = ipsec_setspidx(m, spidx, 1);
 823        if (error)
 824                goto bad;
 825        spidx->dir = IPSEC_DIR_OUTBOUND;
 826
 827        return 0;
 828
 829bad:
 830        bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
 831        bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
 832        return error;
 833}
 834
 835#if INET6
 836static int
 837ipsec6_setspidx_in6pcb(m, pcb)
 838        struct mbuf *m;
 839        struct in6pcb *pcb;
 840{
 841        struct secpolicyindex *spidx;
 842        int error;
 843
 844        /* sanity check */
 845        if (pcb == NULL)
 846                panic("ipsec6_setspidx_in6pcb: no PCB found.\n");
 847        if (pcb->in6p_sp == NULL)
 848                panic("ipsec6_setspidx_in6pcb: no in6p_sp found.\n");
 849        if (pcb->in6p_sp->sp_out == NULL || pcb->in6p_sp->sp_in == NULL)
 850                panic("ipsec6_setspidx_in6pcb: no sp_in/out found.\n");
 851
 852        bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
 853        bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
 854
 855        spidx = &pcb->in6p_sp->sp_in->spidx;
 856        error = ipsec_setspidx(m, spidx, 1);
 857        if (error)
 858                goto bad;
 859        spidx->dir = IPSEC_DIR_INBOUND;
 860
 861        spidx = &pcb->in6p_sp->sp_out->spidx;
 862        error = ipsec_setspidx(m, spidx, 1);
 863        if (error)
 864                goto bad;
 865        spidx->dir = IPSEC_DIR_OUTBOUND;
 866
 867        return 0;
 868
 869bad:
 870        bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
 871        bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
 872        return error;
 873}
 874#endif
 875
 876/*
 877 * configure security policy index (src/dst/proto/sport/dport)
 878 * by looking at the content of mbuf.
 879 * the caller is responsible for error recovery (like clearing up spidx).
 880 */
 881static int
 882ipsec_setspidx(m, spidx, needport)
 883        struct mbuf *m;
 884        struct secpolicyindex *spidx;
 885        int needport;
 886{
 887        struct ip *ip = NULL;
 888        struct ip ipbuf;
 889        u_int v;
 890        struct mbuf *n;
 891        int len;
 892        int error;
 893
 894        if (m == NULL)
 895                panic("ipsec_setspidx: m == 0 passed.\n");
 896
 897        /*
 898         * validate m->m_pkthdr.len.  we see incorrect length if we
 899         * mistakenly call this function with inconsistent mbuf chain
 900         * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
 901         */
 902        len = 0;
 903        for (n = m; n; n = n->m_next)
 904                len += n->m_len;
 905        if (m->m_pkthdr.len != len) {
 906                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 907                        printf("ipsec_setspidx: "
 908                               "total of m_len(%d) != pkthdr.len(%d), "
 909                               "ignored.\n",
 910                                len, m->m_pkthdr.len));
 911                return EINVAL;
 912        }
 913
 914        if (m->m_pkthdr.len < sizeof(struct ip)) {
 915                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 916                        printf("ipsec_setspidx: "
 917                            "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
 918                            m->m_pkthdr.len));
 919                return EINVAL;
 920        }
 921
 922        if (m->m_len >= sizeof(*ip))
 923                ip = mtod(m, struct ip *);
 924        else {
 925                m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
 926                ip = &ipbuf;
 927        }
 928#ifdef _IP_VHL
 929        v = _IP_VHL_V(ip->ip_vhl);
 930#else
 931        v = ip->ip_v;
 932#endif
 933        switch (v) {
 934        case 4:
 935                error = ipsec4_setspidx_ipaddr(m, spidx);
 936                if (error)
 937                        return error;
 938                ipsec4_get_ulp(m, spidx, needport);
 939                return 0;
 940#ifdef INET6
 941        case 6:
 942                if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
 943                        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 944                                printf("ipsec_setspidx: "
 945                                    "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
 946                                    "ignored.\n", m->m_pkthdr.len));
 947                        return EINVAL;
 948                }
 949                error = ipsec6_setspidx_ipaddr(m, spidx);
 950                if (error)
 951                        return error;
 952                ipsec6_get_ulp(m, spidx, needport);
 953                return 0;
 954#endif
 955        default:
 956                KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 957                        printf("ipsec_setspidx: "
 958                            "unknown IP version %u, ignored.\n", v));
 959                return EINVAL;
 960        }
 961}
 962
 963static void
 964ipsec4_get_ulp(m, spidx, needport)
 965        struct mbuf *m;
 966        struct secpolicyindex *spidx;
 967        int needport;
 968{
 969        struct ip ip;
 970        struct ip6_ext ip6e;
 971        u_int8_t nxt;
 972        int off;
 973        struct tcphdr th;
 974        struct udphdr uh;
 975
 976        /* sanity check */
 977        if (m == NULL)
 978                panic("ipsec4_get_ulp: NULL pointer was passed.\n");
 979        if (m->m_pkthdr.len < sizeof(ip))
 980                panic("ipsec4_get_ulp: too short\n");
 981
 982        /* set default */
 983        spidx->ul_proto = IPSEC_ULPROTO_ANY;
 984        ((struct sockaddr_in *)&spidx->src)->sin_port = IPSEC_PORT_ANY;
 985        ((struct sockaddr_in *)&spidx->dst)->sin_port = IPSEC_PORT_ANY;
 986
 987        m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
 988        /* ip_input() flips it into host endian XXX need more checking */
 989        if (ip.ip_off & (IP_MF | IP_OFFMASK))
 990                return;
 991
 992        nxt = ip.ip_p;
 993#ifdef _IP_VHL
 994        off = _IP_VHL_HL(ip->ip_vhl) << 2;
 995#else
 996        off = ip.ip_hl << 2;
 997#endif
 998        while (off < m->m_pkthdr.len) {
 999                switch (nxt) {
1000                case IPPROTO_TCP:
1001                        spidx->ul_proto = nxt;
1002                        if (!needport)
1003                                return;
1004                        if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1005                                return;
1006                        m_copydata(m, off, sizeof(th), (caddr_t)&th);
1007                        ((struct sockaddr_in *)&spidx->src)->sin_port =
1008                            th.th_sport;
1009                        ((struct sockaddr_in *)&spidx->dst)->sin_port =
1010                            th.th_dport;
1011                        return;
1012                case IPPROTO_UDP:
1013                        spidx->ul_proto = nxt;
1014                        if (!needport)
1015                                return;
1016                        if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1017                                return;
1018                        m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1019                        ((struct sockaddr_in *)&spidx->src)->sin_port =
1020                            uh.uh_sport;
1021                        ((struct sockaddr_in *)&spidx->dst)->sin_port =
1022                            uh.uh_dport;
1023                        return;
1024                case IPPROTO_AH:
1025                        if (off + sizeof(ip6e) > m->m_pkthdr.len)
1026                                return;
1027                        m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1028                        off += (ip6e.ip6e_len + 2) << 2;
1029                        nxt = ip6e.ip6e_nxt;
1030                        break;
1031                case IPPROTO_ICMP:
1032                default:
1033                        /* XXX intermediate headers??? */
1034                        spidx->ul_proto = nxt;
1035                        return;
1036                }
1037        }
1038}
1039
1040/* assumes that m is sane */
1041static int
1042ipsec4_setspidx_ipaddr(m, spidx)
1043        struct mbuf *m;
1044        struct secpolicyindex *spidx;
1045{
1046        struct ip *ip = NULL;
1047        struct ip ipbuf;
1048        struct sockaddr_in *sin;
1049
1050        if (m->m_len >= sizeof(*ip))
1051                ip = mtod(m, struct ip *);
1052        else {
1053                m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
1054                ip = &ipbuf;
1055        }
1056
1057        sin = (struct sockaddr_in *)&spidx->src;
1058        bzero(sin, sizeof(*sin));
1059        sin->sin_family = AF_INET;
1060        sin->sin_len = sizeof(struct sockaddr_in);
1061        bcopy(&ip->ip_src, &sin->sin_addr, sizeof(ip->ip_src));
1062        spidx->prefs = sizeof(struct in_addr) << 3;
1063
1064        sin = (struct sockaddr_in *)&spidx->dst;
1065        bzero(sin, sizeof(*sin));
1066        sin->sin_family = AF_INET;
1067        sin->sin_len = sizeof(struct sockaddr_in);
1068        bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst));
1069        spidx->prefd = sizeof(struct in_addr) << 3;
1070        return 0;
1071}
1072
1073#if INET6
1074static void
1075ipsec6_get_ulp(m, spidx, needport)
1076        struct mbuf *m;
1077        struct secpolicyindex *spidx;
1078        int needport;
1079{
1080        int off, nxt;
1081        struct tcphdr th;
1082        struct udphdr uh;
1083
1084        /* sanity check */
1085        if (m == NULL)
1086                panic("ipsec6_get_ulp: NULL pointer was passed.\n");
1087
1088        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1089                printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
1090
1091        /* set default */
1092        spidx->ul_proto = IPSEC_ULPROTO_ANY;
1093        ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
1094        ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
1095
1096        nxt = -1;
1097        off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
1098        if (off < 0 || m->m_pkthdr.len < off)
1099                return;
1100
1101        switch (nxt) {
1102        case IPPROTO_TCP:
1103                spidx->ul_proto = nxt;
1104                if (!needport)
1105                        break;
1106                if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1107                        break;
1108                m_copydata(m, off, sizeof(th), (caddr_t)&th);
1109                ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
1110                ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
1111                break;
1112        case IPPROTO_UDP:
1113                spidx->ul_proto = nxt;
1114                if (!needport)
1115                        break;
1116                if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1117                        break;
1118                m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1119                ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
1120                ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
1121                break;
1122        case IPPROTO_ICMPV6:
1123        default:
1124                /* XXX intermediate headers??? */
1125                spidx->ul_proto = nxt;
1126                break;
1127        }
1128}
1129
1130/* assumes that m is sane */
1131static int
1132ipsec6_setspidx_ipaddr(m, spidx)
1133        struct mbuf *m;
1134        struct secpolicyindex *spidx;
1135{
1136        struct ip6_hdr *ip6 = NULL;
1137        struct ip6_hdr ip6buf;
1138        struct sockaddr_in6 *sin6;
1139
1140        if (m->m_len >= sizeof(*ip6))
1141                ip6 = mtod(m, struct ip6_hdr *);
1142        else {
1143                m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
1144                ip6 = &ip6buf;
1145        }
1146
1147        sin6 = (struct sockaddr_in6 *)&spidx->src;
1148        bzero(sin6, sizeof(*sin6));
1149        sin6->sin6_family = AF_INET6;
1150        sin6->sin6_len = sizeof(struct sockaddr_in6);
1151        bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
1152        if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
1153                sin6->sin6_addr.s6_addr16[1] = 0;
1154                sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
1155        }
1156        spidx->prefs = sizeof(struct in6_addr) << 3;
1157
1158        sin6 = (struct sockaddr_in6 *)&spidx->dst;
1159        bzero(sin6, sizeof(*sin6));
1160        sin6->sin6_family = AF_INET6;
1161        sin6->sin6_len = sizeof(struct sockaddr_in6);
1162        bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
1163        if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
1164                sin6->sin6_addr.s6_addr16[1] = 0;
1165                sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
1166        }
1167        spidx->prefd = sizeof(struct in6_addr) << 3;
1168
1169        return 0;
1170}
1171#endif
1172
1173static struct inpcbpolicy *
1174ipsec_newpcbpolicy()
1175{
1176        struct inpcbpolicy *p;
1177
1178        p = (struct inpcbpolicy *)_MALLOC(sizeof(*p), M_SECA, M_WAITOK);
1179        return p;
1180}
1181
1182static void
1183ipsec_delpcbpolicy(p)
1184        struct inpcbpolicy *p;
1185{
1186        FREE(p, M_SECA);
1187}
1188
1189/* initialize policy in PCB */
1190int
1191ipsec_init_policy(so, pcb_sp)
1192        struct socket *so;
1193        struct inpcbpolicy **pcb_sp;
1194{
1195        struct inpcbpolicy *new;
1196
1197        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1198
1199        /* sanity check. */
1200        if (so == NULL || pcb_sp == NULL)
1201                panic("ipsec_init_policy: NULL pointer was passed.\n");
1202
1203        new = ipsec_newpcbpolicy();
1204        if (new == NULL) {
1205                ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
1206                return ENOBUFS;
1207        }
1208        bzero(new, sizeof(*new));
1209
1210#ifdef __APPLE__
1211        if (so->so_uid == 0)
1212#else
1213        if (so->so_cred != 0 && !suser(so->so_cred->pc_ucred, NULL))
1214#endif
1215                new->priv = 1;
1216        else
1217                new->priv = 0;
1218
1219        if ((new->sp_in = key_newsp()) == NULL) {
1220                ipsec_delpcbpolicy(new);
1221                return ENOBUFS;
1222        }
1223        new->sp_in->state = IPSEC_SPSTATE_ALIVE;
1224        new->sp_in->policy = IPSEC_POLICY_ENTRUST;
1225
1226        if ((new->sp_out = key_newsp()) == NULL) {
1227                key_freesp(new->sp_in);
1228                ipsec_delpcbpolicy(new);
1229                return ENOBUFS;
1230        }
1231        new->sp_out->state = IPSEC_SPSTATE_ALIVE;
1232        new->sp_out->policy = IPSEC_POLICY_ENTRUST;
1233
1234        *pcb_sp = new;
1235
1236        return 0;
1237}
1238
1239/* copy old ipsec policy into new */
1240int
1241ipsec_copy_policy(old, new)
1242        struct inpcbpolicy *old, *new;
1243{
1244        struct secpolicy *sp;
1245
1246        if (ipsec_bypass != 0)
1247                return 0;
1248
1249        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1250
1251        sp = ipsec_deepcopy_policy(old->sp_in);
1252        if (sp) {
1253                key_freesp(new->sp_in);
1254                new->sp_in = sp;
1255        } else
1256                return ENOBUFS;
1257
1258        sp = ipsec_deepcopy_policy(old->sp_out);
1259        if (sp) {
1260                key_freesp(new->sp_out);
1261                new->sp_out = sp;
1262        } else
1263                return ENOBUFS;
1264
1265        new->priv = old->priv;
1266
1267        return 0;
1268}
1269
1270/* deep-copy a policy in PCB */
1271static struct secpolicy *
1272ipsec_deepcopy_policy(src)
1273        struct secpolicy *src;
1274{
1275        struct ipsecrequest *newchain = NULL;
1276        struct ipsecrequest *p;
1277        struct ipsecrequest **q;
1278        struct ipsecrequest *r;
1279        struct secpolicy *dst;
1280
1281        dst = key_newsp();
1282        if (src == NULL || dst == NULL)
1283                return NULL;
1284
1285        /*
1286         * deep-copy IPsec request chain.  This is required since struct
1287         * ipsecrequest is not reference counted.
1288         */
1289        q = &newchain;
1290        for (p = src->req; p; p = p->next) {
1291                *q = (struct ipsecrequest *)_MALLOC(sizeof(struct ipsecrequest),
1292                        M_SECA, M_WAITOK);
1293                if (*q == NULL)
1294                        goto fail;
1295                bzero(*q, sizeof(**q));
1296                (*q)->next = NULL;
1297
1298                (*q)->saidx.proto = p->saidx.proto;
1299                (*q)->saidx.mode = p->saidx.mode;
1300                (*q)->level = p->level;
1301                (*q)->saidx.reqid = p->saidx.reqid;
1302
1303                bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
1304                bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
1305
1306                (*q)->sav = NULL;
1307                (*q)->sp = dst;
1308
1309                q = &((*q)->next);
1310        }
1311
1312        dst->req = newchain;
1313        dst->state = src->state;
1314        dst->policy = src->policy;
1315        /* do not touch the refcnt fields */
1316
1317        return dst;
1318
1319fail:
1320        for (p = newchain; p; p = r) {
1321                r = p->next;
1322                FREE(p, M_SECA);
1323                p = NULL;
1324        }
1325        return NULL;
1326}
1327
1328/* set policy and ipsec request if present. */
1329static int
1330ipsec_set_policy(pcb_sp, optname, request, len, priv)
1331        struct secpolicy **pcb_sp;
1332        int optname;
1333        caddr_t request;
1334        size_t len;
1335        int priv;
1336{
1337        struct sadb_x_policy *xpl;
1338        struct secpolicy *newsp = NULL;
1339        int error;
1340
1341        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1342
1343        /* sanity check. */
1344        if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
1345                return EINVAL;
1346        if (len < sizeof(*xpl))
1347                return EINVAL;
1348        xpl = (struct sadb_x_policy *)request;
1349
1350        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1351                printf("ipsec_set_policy: passed policy\n");
1352                kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1353
1354        /* check policy type */
1355        /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1356        if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
1357         || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1358                return EINVAL;
1359
1360        /* check privileged socket */
1361        if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
1362                return EACCES;
1363
1364        /* allocation new SP entry */
1365        if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1366                return error;
1367
1368        newsp->state = IPSEC_SPSTATE_ALIVE;
1369
1370        /* clear old SP and set new SP */
1371        key_freesp(*pcb_sp);
1372        *pcb_sp = newsp;
1373        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1374                printf("ipsec_set_policy: new policy\n");
1375                kdebug_secpolicy(newsp));
1376
1377        return 0;
1378}
1379
1380static int
1381ipsec_get_policy(pcb_sp, mp)
1382        struct secpolicy *pcb_sp;
1383        struct mbuf **mp;
1384{
1385
1386        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1387
1388        /* sanity check. */
1389        if (pcb_sp == NULL || mp == NULL)
1390                return EINVAL;
1391
1392        *mp = key_sp2msg(pcb_sp);
1393        if (!*mp) {
1394                ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
1395                return ENOBUFS;
1396        }
1397
1398        (*mp)->m_type = MT_DATA;
1399        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1400                printf("ipsec_get_policy:\n");
1401                kdebug_mbuf(*mp));
1402
1403        return 0;
1404}
1405
1406int
1407ipsec4_set_policy(inp, optname, request, len, priv)
1408        struct inpcb *inp;
1409        int optname;
1410        caddr_t request;
1411        size_t len;
1412        int priv;
1413{
1414        struct sadb_x_policy *xpl;
1415        struct secpolicy **pcb_sp;
1416        int     error = 0;
1417
1418        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1419
1420        /* sanity check. */
1421        if (inp == NULL || request == NULL)
1422                return EINVAL;
1423        if (len < sizeof(*xpl))
1424                return EINVAL;
1425        xpl = (struct sadb_x_policy *)request;
1426
1427        if (inp->inp_sp == NULL) {
1428                error = ipsec_init_policy(inp->inp_socket, &inp->inp_sp);
1429                if (error)
1430                        return error;
1431        }
1432
1433        /* select direction */
1434        switch (xpl->sadb_x_policy_dir) {
1435        case IPSEC_DIR_INBOUND:
1436                pcb_sp = &inp->inp_sp->sp_in;
1437                break;
1438        case IPSEC_DIR_OUTBOUND:
1439                pcb_sp = &inp->inp_sp->sp_out;
1440                break;
1441        default:
1442                ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1443                        xpl->sadb_x_policy_dir));
1444                return EINVAL;
1445        }
1446
1447        /* turn bypass off */
1448        if (ipsec_bypass != 0)
1449                ipsec_bypass = 0;
1450
1451        return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1452}
1453
1454int
1455ipsec4_get_policy(inp, request, len, mp)
1456        struct inpcb *inp;
1457        caddr_t request;
1458        size_t len;
1459        struct mbuf **mp;
1460{
1461        struct sadb_x_policy *xpl;
1462        struct secpolicy *pcb_sp;
1463        int     error = 0;
1464
1465        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1466
1467        /* sanity check. */
1468        if (inp == NULL || request == NULL || mp == NULL)
1469                return EINVAL;
1470        if (len < sizeof(*xpl))
1471                return EINVAL;
1472        xpl = (struct sadb_x_policy *)request;
1473        
1474        if (inp->inp_sp == NULL) {
1475                error = ipsec_init_policy(inp->inp_socket, &inp->inp_sp);
1476                if (error)
1477                        return error;
1478        }
1479
1480        /* select direction */
1481        switch (xpl->sadb_x_policy_dir) {
1482        case IPSEC_DIR_INBOUND:
1483                pcb_sp = inp->inp_sp->sp_in;
1484                break;
1485        case IPSEC_DIR_OUTBOUND:
1486                pcb_sp = inp->inp_sp->sp_out;
1487                break;
1488        default:
1489                ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1490                        xpl->sadb_x_policy_dir));
1491                return EINVAL;
1492        }
1493
1494        return ipsec_get_policy(pcb_sp, mp);
1495}
1496
1497/* delete policy in PCB */
1498int
1499ipsec4_delete_pcbpolicy(inp)
1500        struct inpcb *inp;
1501{
1502        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1503
1504        /* sanity check. */
1505        if (inp == NULL)
1506                panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n");
1507
1508        if (inp->inp_sp == NULL)
1509                return 0;
1510
1511        if (inp->inp_sp->sp_in != NULL) {
1512                key_freesp(inp->inp_sp->sp_in);
1513                inp->inp_sp->sp_in = NULL;
1514        }
1515
1516        if (inp->inp_sp->sp_out != NULL) {
1517                key_freesp(inp->inp_sp->sp_out);
1518                inp->inp_sp->sp_out = NULL;
1519        }
1520
1521        ipsec_delpcbpolicy(inp->inp_sp);
1522        inp->inp_sp = NULL;
1523
1524        return 0;
1525}
1526
1527#if INET6
1528int
1529ipsec6_set_policy(in6p, optname, request, len, priv)
1530        struct in6pcb *in6p;
1531        int optname;
1532        caddr_t request;
1533        size_t len;
1534        int priv;
1535{
1536        struct sadb_x_policy *xpl;
1537        struct secpolicy **pcb_sp;
1538        int error = 0;
1539
1540        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1541
1542        /* sanity check. */
1543        if (in6p == NULL || request == NULL)
1544                return EINVAL;
1545        if (len < sizeof(*xpl))
1546                return EINVAL;
1547        xpl = (struct sadb_x_policy *)request;
1548        
1549        if (in6p->in6p_sp == NULL) {
1550                error = ipsec_init_policy(in6p->inp_socket, &in6p->in6p_sp);
1551                if (error)
1552                        return error;
1553        }
1554
1555        /* select direction */
1556        switch (xpl->sadb_x_policy_dir) {
1557        case IPSEC_DIR_INBOUND:
1558                pcb_sp = &in6p->in6p_sp->sp_in;
1559                break;
1560        case IPSEC_DIR_OUTBOUND:
1561                pcb_sp = &in6p->in6p_sp->sp_out;
1562                break;
1563        default:
1564                ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1565                        xpl->sadb_x_policy_dir));
1566                return EINVAL;
1567        }
1568
1569        /* turn bypass off */
1570        if (ipsec_bypass != 0)
1571                ipsec_bypass = 0;
1572
1573        return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1574}
1575
1576int
1577ipsec6_get_policy(in6p, request, len, mp)
1578        struct in6pcb *in6p;
1579        caddr_t request;
1580        size_t len;
1581        struct mbuf **mp;
1582{
1583        struct sadb_x_policy *xpl;
1584        struct secpolicy *pcb_sp;
1585        int error = 0;
1586
1587        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1588
1589        /* sanity check. */
1590        if (in6p == NULL || request == NULL || mp == NULL)
1591                return EINVAL;
1592        if (len < sizeof(*xpl))
1593                return EINVAL;
1594        xpl = (struct sadb_x_policy *)request;
1595        
1596        if (in6p->in6p_sp == NULL) {
1597                error = ipsec_init_policy(in6p->inp_socket, &in6p->in6p_sp);
1598                if (error)
1599                        return error;
1600        }
1601
1602        /* select direction */
1603        switch (xpl->sadb_x_policy_dir) {
1604        case IPSEC_DIR_INBOUND:
1605                pcb_sp = in6p->in6p_sp->sp_in;
1606                break;
1607        case IPSEC_DIR_OUTBOUND:
1608                pcb_sp = in6p->in6p_sp->sp_out;
1609                break;
1610        default:
1611                ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1612                        xpl->sadb_x_policy_dir));
1613                return EINVAL;
1614        }
1615
1616        return ipsec_get_policy(pcb_sp, mp);
1617}
1618
1619int
1620ipsec6_delete_pcbpolicy(in6p)
1621        struct in6pcb *in6p;
1622{
1623        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1624
1625        /* sanity check. */
1626        if (in6p == NULL)
1627                panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n");
1628
1629        if (in6p->in6p_sp == NULL)
1630                return 0;
1631
1632        if (in6p->in6p_sp->sp_in != NULL) {
1633                key_freesp(in6p->in6p_sp->sp_in);
1634                in6p->in6p_sp->sp_in = NULL;
1635        }
1636
1637        if (in6p->in6p_sp->sp_out != NULL) {
1638                key_freesp(in6p->in6p_sp->sp_out);
1639                in6p->in6p_sp->sp_out = NULL;
1640        }
1641
1642        ipsec_delpcbpolicy(in6p->in6p_sp);
1643        in6p->in6p_sp = NULL;
1644
1645        return 0;
1646}
1647#endif
1648
1649/*
1650 * return current level.
1651 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1652 */
1653u_int
1654ipsec_get_reqlevel(isr)
1655        struct ipsecrequest *isr;
1656{
1657        u_int level = 0;
1658        u_int esp_trans_deflev, esp_net_deflev, ah_trans_deflev, ah_net_deflev;
1659
1660        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1661
1662        /* sanity check */
1663        if (isr == NULL || isr->sp == NULL)
1664                panic("ipsec_get_reqlevel: NULL pointer is passed.\n");
1665        if (((struct sockaddr *)&isr->sp->spidx.src)->sa_family
1666                        != ((struct sockaddr *)&isr->sp->spidx.dst)->sa_family)
1667                panic("ipsec_get_reqlevel: family mismatched.\n");
1668
1669/* XXX note that we have ipseclog() expanded here - code sync issue */
1670#define IPSEC_CHECK_DEFAULT(lev) \
1671        (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE            \
1672                        && (lev) != IPSEC_LEVEL_UNIQUE)                       \
1673                ? (ipsec_debug                                                \
1674                        ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1675                                (lev), IPSEC_LEVEL_REQUIRE)                   \
1676                        : 0),                                                 \
1677                        (lev) = IPSEC_LEVEL_REQUIRE,                          \
1678                        (lev)                                                 \
1679                : (lev))
1680
1681        /* set default level */
1682        switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
1683#if INET
1684        case AF_INET:
1685                esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1686                esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1687                ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1688                ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1689                break;
1690#endif
1691#if INET6
1692        case AF_INET6:
1693                esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1694                esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1695                ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1696                ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1697                break;
1698#endif /* INET6 */
1699        default:
1700                panic("key_get_reqlevel: Unknown family. %d\n",
1701                        ((struct sockaddr *)&isr->sp->spidx.src)->sa_family);
1702        }
1703
1704#undef IPSEC_CHECK_DEFAULT
1705
1706        /* set level */
1707        switch (isr->level) {
1708        case IPSEC_LEVEL_DEFAULT:
1709                switch (isr->saidx.proto) {
1710                case IPPROTO_ESP:
1711                        if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1712                                level = esp_net_deflev;
1713                        else
1714                                level = esp_trans_deflev;
1715                        break;
1716                case IPPROTO_AH:
1717                        if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1718                                level = ah_net_deflev;
1719                        else
1720                                level = ah_trans_deflev;
1721                        break;
1722                case IPPROTO_IPCOMP:
1723                        /*
1724                         * we don't really care, as IPcomp document says that
1725                         * we shouldn't compress small packets
1726                         */
1727                        level = IPSEC_LEVEL_USE;
1728                        break;
1729                default:
1730                        panic("ipsec_get_reqlevel: "
1731                                "Illegal protocol defined %u\n",
1732                                isr->saidx.proto);
1733                }
1734                break;
1735
1736        case IPSEC_LEVEL_USE:
1737        case IPSEC_LEVEL_REQUIRE:
1738                level = isr->level;
1739                break;
1740        case IPSEC_LEVEL_UNIQUE:
1741                level = IPSEC_LEVEL_REQUIRE;
1742                break;
1743
1744        default:
1745                panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
1746                        isr->level);
1747        }
1748
1749        return level;
1750}
1751
1752/*
1753 * Check AH/ESP integrity.
1754 * OUT:
1755 *      0: valid
1756 *      1: invalid
1757 */
1758static int
1759ipsec_in_reject(sp, m)
1760        struct secpolicy *sp;
1761        struct mbuf *m;
1762{
1763        struct ipsecrequest *isr;
1764        u_int level;
1765        int need_auth, need_conf, need_icv;
1766
1767        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1768                printf("ipsec_in_reject: using SP\n");
1769                kdebug_secpolicy(sp));
1770
1771        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1772
1773        /* check policy */
1774        switch (sp->policy) {
1775        case IPSEC_POLICY_DISCARD:
1776                return 1;
1777        case IPSEC_POLICY_BYPASS:
1778        case IPSEC_POLICY_NONE:
1779                return 0;
1780        
1781        case IPSEC_POLICY_IPSEC:
1782                break;
1783
1784        case IPSEC_POLICY_ENTRUST:
1785        default:
1786                panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp->policy);
1787        }
1788
1789        need_auth = 0;
1790        need_conf = 0;
1791        need_icv = 0;
1792
1793        /* XXX should compare policy against ipsec header history */
1794
1795        for (isr = sp->req; isr != NULL; isr = isr->next) {
1796
1797                /* get current level */
1798                level = ipsec_get_reqlevel(isr);
1799
1800                switch (isr->saidx.proto) {
1801                case IPPROTO_ESP:
1802                        if (level == IPSEC_LEVEL_REQUIRE) {
1803                                need_conf++;
1804
1805                                if (isr->sav != NULL
1806                                 && isr->sav->flags == SADB_X_EXT_NONE
1807                                 && isr->sav->alg_auth != SADB_AALG_NONE)
1808                                        need_icv++;
1809                        }
1810                        break;
1811                case IPPROTO_AH:
1812                        if (level == IPSEC_LEVEL_REQUIRE) {
1813                                need_auth++;
1814                                need_icv++;
1815                        }
1816                        break;
1817                case IPPROTO_IPCOMP:
1818                        /*
1819                         * we don't really care, as IPcomp document says that
1820                         * we shouldn't compress small packets, IPComp policy
1821                         * should always be treated as being in "use" level.
1822                         */
1823                        break;
1824                }
1825        }
1826
1827        KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1828                printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1829                        need_auth, need_conf, need_icv, m->m_flags));
1830
1831        if ((need_conf && !(m->m_flags & M_DECRYPTED))
1832         || (!need_auth && need_icv && !(m->m_flags & M_AUTHIPDGM))
1833         || (need_auth && !(m->m_flags & M_AUTHIPHDR)))
1834                return 1;
1835
1836        return 0;
1837}
1838
1839/*
1840 * Check AH/ESP integrity.
1841 * This function is called from tcp_input(), udp_input(),
1842 * and {ah,esp}4_input for tunnel mode
1843 */
1844int
1845ipsec4_in_reject_so(m, so)
1846        struct mbuf *m;
1847        struct socket *so;
1848{
1849        struct secpolicy *sp = NULL;
1850        int error;
1851        int result;
1852
1853        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1854
1855        /* sanity check */
1856        if (m == NULL)
1857                return 0;       /* XXX should be panic ? */
1858
1859        /* get SP for this packet.
1860         * When we are called from ip_forward(), we call
1861         * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1862         */
1863        if (so == NULL)
1864                sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1865        else
1866                sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1867
1868        if (sp == NULL)
1869                return 0;       /* XXX should be panic ?
1870                                 * -> No, there may be error. */
1871
1872        result = ipsec_in_reject(sp, m);
1873        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1874                printf("DP ipsec4_in_reject_so call free SP:%p\n", sp));
1875        key_freesp(sp);
1876
1877        return result;
1878}
1879
1880int
1881ipsec4_in_reject(m, inp)
1882        struct mbuf *m;
1883        struct inpcb *inp;
1884{
1885        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1886
1887        if (inp == NULL)
1888                return ipsec4_in_reject_so(m, NULL);
1889        if (inp->inp_socket)
1890                return ipsec4_in_reject_so(m, inp->inp_socket);
1891        else
1892                panic("ipsec4_in_reject: invalid inpcb/socket");
1893
1894        /* NOTREACHED */
1895        return 0;
1896}
1897
1898#if INET6
1899/*
1900 * Check AH/ESP integrity.
1901 * This function is called from tcp6_input(), udp6_input(),
1902 * and {ah,esp}6_input for tunnel mode
1903 */
1904int
1905ipsec6_in_reject_so(m, so)
1906        struct mbuf *m;
1907        struct socket *so;
1908{
1909        struct secpolicy *sp = NULL;
1910        int error;
1911        int result;
1912
1913        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1914
1915        /* sanity check */
1916        if (m == NULL)
1917                return 0;       /* XXX should be panic ? */
1918
1919        /* get SP for this packet.
1920         * When we are called from ip_forward(), we call
1921         * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
1922         */
1923        if (so == NULL)
1924                sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1925        else
1926                sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1927
1928        if (sp == NULL)
1929                return 0;       /* XXX should be panic ? */
1930
1931        result = ipsec_in_reject(sp, m);
1932        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1933                printf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
1934        key_freesp(sp);
1935
1936        return result;
1937}
1938
1939int
1940ipsec6_in_reject(m, in6p)
1941        struct mbuf *m;
1942        struct in6pcb *in6p;
1943{
1944        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1945
1946        if (in6p == NULL)
1947                return ipsec6_in_reject_so(m, NULL);
1948        if (in6p->in6p_socket)
1949                return ipsec6_in_reject_so(m, in6p->in6p_socket);
1950        else
1951                panic("ipsec6_in_reject: invalid in6p/socket");
1952
1953        /* NOTREACHED */
1954        return 0;
1955}
1956#endif
1957
1958/*
1959 * compute the byte size to be occupied by IPsec header.
1960 * in case it is tunneled, it includes the size of outer IP header.
1961 * NOTE: SP passed is free in this function.
1962 */
1963static size_t
1964ipsec_hdrsiz(sp)
1965        struct secpolicy *sp;
1966{
1967        struct ipsecrequest *isr;
1968        size_t siz, clen;
1969
1970        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1971                printf("ipsec_hdrsiz: using SP\n");
1972                kdebug_secpolicy(sp));
1973
1974        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
1975
1976        /* check policy */
1977        switch (sp->policy) {
1978        case IPSEC_POLICY_DISCARD:
1979        case IPSEC_POLICY_BYPASS:
1980        case IPSEC_POLICY_NONE:
1981                return 0;
1982        
1983        case IPSEC_POLICY_IPSEC:
1984                break;
1985
1986        case IPSEC_POLICY_ENTRUST:
1987        default:
1988                panic("ipsec_hdrsiz: Invalid policy found. %d\n", sp->policy);
1989        }
1990
1991        siz = 0;
1992
1993        for (isr = sp->req; isr != NULL; isr = isr->next) {
1994
1995                clen = 0;
1996
1997                switch (isr->saidx.proto) {
1998                case IPPROTO_ESP:
1999#if IPSEC_ESP
2000                        clen = esp_hdrsiz(isr);
2001#else
2002                        clen = 0;       /*XXX*/
2003#endif
2004                        break;
2005                case IPPROTO_AH:
2006                        clen = ah_hdrsiz(isr);
2007                        break;
2008                case IPPROTO_IPCOMP:
2009                        clen = sizeof(struct ipcomp);
2010                        break;
2011                }
2012
2013                if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2014                        switch (((struct sockaddr *)&isr->saidx.dst)->sa_family) {
2015                        case AF_INET:
2016                                clen += sizeof(struct ip);
2017                                break;
2018#if INET6
2019                        case AF_INET6:
2020                                clen += sizeof(struct ip6_hdr);
2021                                break;
2022#endif
2023                        default:
2024                                ipseclog((LOG_ERR, "ipsec_hdrsiz: "
2025                                    "unknown AF %d in IPsec tunnel SA\n",
2026                                    ((struct sockaddr *)&isr->saidx.dst)->sa_family));
2027                                break;
2028                        }
2029                }
2030                siz += clen;
2031        }
2032
2033        return siz;
2034}
2035
2036/* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
2037size_t
2038ipsec4_hdrsiz(m, dir, inp)
2039        struct mbuf *m;
2040        u_int dir;
2041        struct inpcb *inp;
2042{
2043        struct secpolicy *sp = NULL;
2044        int error;
2045        size_t size;
2046
2047        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2048
2049        /* sanity check */
2050        if (m == NULL)
2051                return 0;       /* XXX should be panic ? */
2052        if (inp != NULL && inp->inp_socket == NULL)
2053                panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
2054
2055        /* get SP for this packet.
2056         * When we are called from ip_forward(), we call
2057         * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2058         */
2059        if (inp == NULL)
2060                sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2061        else
2062                sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
2063
2064        if (sp == NULL)
2065                return 0;       /* XXX should be panic ? */
2066
2067        size = ipsec_hdrsiz(sp);
2068        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2069                printf("DP ipsec4_hdrsiz call free SP:%p\n", sp));
2070        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2071                printf("ipsec4_hdrsiz: size:%lu.\n", (unsigned long)size));
2072        key_freesp(sp);
2073
2074        return size;
2075}
2076
2077#if INET6
2078/* This function is called from ipsec6_hdrsize_tcp(),
2079 * and maybe from ip6_forward.()
2080 */
2081size_t
2082ipsec6_hdrsiz(m, dir, in6p)
2083        struct mbuf *m;
2084        u_int dir;
2085        struct in6pcb *in6p;
2086{
2087        struct secpolicy *sp = NULL;
2088        int error;
2089        size_t size;
2090
2091        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2092
2093        /* sanity check */
2094        if (m == NULL)
2095                return 0;       /* XXX shoud be panic ? */
2096        if (in6p != NULL && in6p->in6p_socket == NULL)
2097                panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2098
2099        /* get SP for this packet */
2100        /* XXX Is it right to call with IP_FORWARDING. */
2101        if (in6p == NULL)
2102                sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2103        else
2104                sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
2105
2106        if (sp == NULL)
2107                return 0;
2108        size = ipsec_hdrsiz(sp);
2109        KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2110                printf("DP ipsec6_hdrsiz call free SP:%p\n", sp));
2111        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2112                printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
2113        key_freesp(sp);
2114
2115        return size;
2116}
2117#endif /*INET6*/
2118
2119#if INET
2120/*
2121 * encapsulate for ipsec tunnel.
2122 * ip->ip_src must be fixed later on.
2123 */
2124static int
2125ipsec4_encapsulate(m, sav)
2126        struct mbuf *m;
2127        struct secasvar *sav;
2128{
2129        struct ip *oip;
2130        struct ip *ip;
2131        size_t hlen;
2132        size_t plen;
2133
2134        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2135
2136        /* can't tunnel between different AFs */
2137        if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2138                != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2139         || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
2140                m_freem(m);
2141                return EINVAL;
2142        }
2143#if 0
2144        /* XXX if the dst is myself, perform nothing. */
2145        if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
2146                m_freem(m);
2147                return EINVAL;
2148        }
2149#endif
2150
2151        if (m->m_len < sizeof(*ip))
2152                panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2153
2154        ip = mtod(m, struct ip *);
2155#ifdef _IP_VHL
2156        hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
2157#else
2158        hlen = ip->ip_hl << 2;
2159#endif
2160
2161        if (m->m_len != hlen)
2162                panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2163
2164        /* generate header checksum */
2165        ip->ip_sum = 0;
2166#ifdef _IP_VHL
2167        ip->ip_sum = in_cksum(m, hlen);
2168#else
2169        ip->ip_sum = in_cksum(m, hlen);
2170#endif
2171
2172        plen = m->m_pkthdr.len;
2173
2174        /*
2175         * grow the mbuf to accomodate the new IPv4 header.
2176         * NOTE: IPv4 options will never be copied.
2177         */
2178        if (M_LEADINGSPACE(m->m_next) < hlen) {
2179                struct mbuf *n;
2180                MGET(n, M_DONTWAIT, MT_DATA);
2181                if (!n) {
2182                        m_freem(m);
2183                        return ENOBUFS;
2184                }
2185                n->m_len = hlen;
2186                n->m_next = m->m_next;
2187                m->m_next = n;
2188                m->m_pkthdr.len += hlen;
2189                oip = mtod(n, struct ip *);
2190        } else {
2191                m->m_next->m_len += hlen;
2192                m->m_next->m_data -= hlen;
2193                m->m_pkthdr.len += hlen;
2194                oip = mtod(m->m_next, struct ip *);
2195        }
2196        ip = mtod(m, struct ip *);
2197        ovbcopy((caddr_t)ip, (caddr_t)oip, hlen);
2198        m->m_len = sizeof(struct ip);
2199        m->m_pkthdr.len -= (hlen - sizeof(struct ip));
2200
2201        /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2202        /* ECN consideration. */
2203        ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2204#ifdef _IP_VHL
2205        ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2);
2206#else
2207        ip->ip_hl = sizeof(struct ip) >> 2;
2208#endif
2209        ip->ip_off &= htons(~IP_OFFMASK);
2210        ip->ip_off &= htons(~IP_MF);
2211        switch (ip4_ipsec_dfbit) {
2212        case 0: /* clear DF bit */
2213                ip->ip_off &= htons(~IP_DF);
2214                break;
2215        case 1: /* set DF bit */
2216                ip->ip_off |= htons(IP_DF);
2217                break;
2218        default:        /* copy DF bit */
2219                break;
2220        }
2221        ip->ip_p = IPPROTO_IPIP;
2222        if (plen + sizeof(struct ip) < IP_MAXPACKET)
2223                ip->ip_len = htons(plen + sizeof(struct ip));
2224        else {
2225                ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2226                        "leave ip_len as is (invalid packet)\n"));
2227        }
2228#ifdef RANDOM_IP_ID
2229        ip->ip_id = ip_randomid();
2230#else
2231        ip->ip_id = htons(ip_id++);
2232#endif
2233        bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
2234                &ip->ip_src, sizeof(ip->ip_src));
2235        bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
2236                &ip->ip_dst, sizeof(ip->ip_dst));
2237        ip->ip_ttl = IPDEFTTL;
2238
2239        /* XXX Should ip_src be updated later ? */
2240
2241        return 0;
2242}
2243#endif /*INET*/
2244
2245#if INET6
2246static int
2247ipsec6_encapsulate(m, sav)
2248        struct mbuf *m;
2249        struct secasvar *sav;
2250{
2251        struct ip6_hdr *oip6;
2252        struct ip6_hdr *ip6;
2253        size_t plen;
2254
2255        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2256
2257        /* can't tunnel between different AFs */
2258        if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2259                != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2260         || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET6) {
2261                m_freem(m);
2262                return EINVAL;
2263        }
2264#if 0
2265        /* XXX if the dst is myself, perform nothing. */
2266        if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
2267                m_freem(m);
2268                return EINVAL;
2269        }
2270#endif
2271
2272        plen = m->m_pkthdr.len;
2273
2274        /*
2275         * grow the mbuf to accomodate the new IPv6 header.
2276         */
2277        if (m->m_len != sizeof(struct ip6_hdr))
2278                panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2279        if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2280                struct mbuf *n;
2281                MGET(n, M_DONTWAIT, MT_DATA);
2282                if (!n) {
2283                        m_freem(m);
2284                        return ENOBUFS;
2285                }
2286                n->m_len = sizeof(struct ip6_hdr);
2287                n->m_next = m->m_next;
2288                m->m_next = n;
2289                m->m_pkthdr.len += sizeof(struct ip6_hdr);
2290                oip6 = mtod(n, struct ip6_hdr *);
2291        } else {
2292                m->m_next->m_len += sizeof(struct ip6_hdr);
2293                m->m_next->m_data -= sizeof(struct ip6_hdr);
2294                m->m_pkthdr.len += sizeof(struct ip6_hdr);
2295                oip6 = mtod(m->m_next, struct ip6_hdr *);
2296        }
2297        ip6 = mtod(m, struct ip6_hdr *);
2298        ovbcopy((caddr_t)ip6, (caddr_t)oip6, sizeof(struct ip6_hdr));
2299
2300        /* Fake link-local scope-class addresses */
2301        if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src))
2302                oip6->ip6_src.s6_addr16[1] = 0;
2303        if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst))
2304                oip6->ip6_dst.s6_addr16[1] = 0;
2305
2306        /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2307        /* ECN consideration. */
2308        ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
2309        if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr))
2310                ip6->ip6_plen = htons(plen);
2311        else {
2312                /* ip6->ip6_plen will be updated in ip6_output() */
2313        }
2314        ip6->ip6_nxt = IPPROTO_IPV6;
2315        bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.src)->sin6_addr,
2316                &ip6->ip6_src, sizeof(ip6->ip6_src));
2317        bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.dst)->sin6_addr,
2318                &ip6->ip6_dst, sizeof(ip6->ip6_dst));
2319        ip6->ip6_hlim = IPV6_DEFHLIM;
2320
2321        /* XXX Should ip6_src be updated later ? */
2322
2323        return 0;
2324}
2325#endif /*INET6*/
2326
2327/*
2328 * Check the variable replay window.
2329 * ipsec_chkreplay() performs replay check before ICV verification.
2330 * ipsec_updatereplay() updates replay bitmap.  This must be called after
2331 * ICV verification (it also performs replay check, which is usually done
2332 * beforehand).
2333 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2334 *
2335 * based on RFC 2401.
2336 */
2337int
2338ipsec_chkreplay(seq, sav)
2339        u_int32_t seq;
2340        struct secasvar *sav;
2341{
2342        const struct secreplay *replay;
2343        u_int32_t diff;
2344        int fr;
2345        u_int32_t wsizeb;       /* constant: bits of window size */
2346        int frlast;             /* constant: last frame */
2347
2348        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2349
2350        /* sanity check */
2351        if (sav == NULL)
2352                panic("ipsec_chkreplay: NULL pointer was passed.\n");
2353
2354        replay = sav->replay;
2355
2356        if (replay->wsize == 0)
2357                return 1;       /* no need to check replay. */
2358
2359        /* constant */
2360        frlast = replay->wsize - 1;
2361        wsizeb = replay->wsize << 3;
2362
2363        /* sequence number of 0 is invalid */
2364        if (seq == 0)
2365                return 0;
2366
2367        /* first time is always okay */
2368        if (replay->count == 0)
2369                return 1;
2370
2371        if (seq > replay->lastseq) {
2372                /* larger sequences are okay */
2373                return 1;
2374        } else {
2375                /* seq is equal or less than lastseq. */
2376                diff = replay->lastseq - seq;
2377
2378                /* over range to check, i.e. too old or wrapped */
2379                if (diff >= wsizeb)
2380                        return 0;
2381
2382                fr = frlast - diff / 8;
2383
2384                /* this packet already seen ? */
2385                if ((replay->bitmap)[fr] & (1 << (diff % 8)))
2386                        return 0;
2387
2388                /* out of order but good */
2389                return 1;
2390        }
2391}
2392
2393/*
2394 * check replay counter whether to update or not.
2395 * OUT: 0:      OK
2396 *      1:      NG
2397 */
2398int
2399ipsec_updatereplay(seq, sav)
2400        u_int32_t seq;
2401        struct secasvar *sav;
2402{
2403        struct secreplay *replay;
2404        u_int32_t diff;
2405        int fr;
2406        u_int32_t wsizeb;       /* constant: bits of window size */
2407        int frlast;             /* constant: last frame */
2408
2409        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2410
2411        /* sanity check */
2412        if (sav == NULL)
2413                panic("ipsec_chkreplay: NULL pointer was passed.\n");
2414
2415        replay = sav->replay;
2416
2417        if (replay->wsize == 0)
2418                goto ok;        /* no need to check replay. */
2419
2420        /* constant */
2421        frlast = replay->wsize - 1;
2422        wsizeb = replay->wsize << 3;
2423
2424        /* sequence number of 0 is invalid */
2425        if (seq == 0)
2426                return 1;
2427
2428        /* first time */
2429        if (replay->count == 0) {
2430                replay->lastseq = seq;
2431                bzero(replay->bitmap, replay->wsize);
2432                (replay->bitmap)[frlast] = 1;
2433                goto ok;
2434        }
2435
2436        if (seq > replay->lastseq) {
2437                /* seq is larger than lastseq. */
2438                diff = seq - replay->lastseq;
2439
2440                /* new larger sequence number */
2441                if (diff < wsizeb) {
2442                        /* In window */
2443                        /* set bit for this packet */
2444                        vshiftl(replay->bitmap, diff, replay->wsize);
2445                        (replay->bitmap)[frlast] |= 1;
2446                } else {
2447                        /* this packet has a "way larger" */
2448                        bzero(replay->bitmap, replay->wsize);
2449                        (replay->bitmap)[frlast] = 1;
2450                }
2451                replay->lastseq = seq;
2452
2453                /* larger is good */
2454        } else {
2455                /* seq is equal or less than lastseq. */
2456                diff = replay->lastseq - seq;
2457
2458                /* over range to check, i.e. too old or wrapped */
2459                if (diff >= wsizeb)
2460                        return 1;
2461
2462                fr = frlast - diff / 8;
2463
2464                /* this packet already seen ? */
2465                if ((replay->bitmap)[fr] & (1 << (diff % 8)))
2466                        return 1;
2467
2468                /* mark as seen */
2469                (replay->bitmap)[fr] |= (1 << (diff % 8));
2470
2471                /* out of order but good */
2472        }
2473
2474ok:
2475        if (replay->count == ~0) {
2476
2477                /* set overflow flag */
2478                replay->overflow++;
2479
2480                /* don't increment, no more packets accepted */
2481                if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
2482                        return 1;
2483
2484                ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
2485                    replay->overflow, ipsec_logsastr(sav)));
2486        }
2487
2488        replay->count++;
2489
2490        return 0;
2491}
2492
2493/*
2494 * shift variable length buffer to left.
2495 * IN:  bitmap: pointer to the buffer
2496 *      nbit:   the number of to shift.
2497 *      wsize:  buffer size (bytes).
2498 */
2499static void
2500vshiftl(bitmap, nbit, wsize)
2501        unsigned char *bitmap;
2502        int nbit, wsize;
2503{
2504        int s, j, i;
2505        unsigned char over;
2506
2507        for (j = 0; j < nbit; j += 8) {
2508                s = (nbit - j < 8) ? (nbit - j): 8;
2509                bitmap[0] <<= s;
2510                for (i = 1; i < wsize; i++) {
2511                        over = (bitmap[i] >> (8 - s));
2512                        bitmap[i] <<= s;
2513                        bitmap[i-1] |= over;
2514                }
2515        }
2516
2517        return;
2518}
2519
2520const char *
2521ipsec4_logpacketstr(ip, spi)
2522        struct ip *ip;
2523        u_int32_t spi;
2524{
2525        static char buf[256];
2526        char *p;
2527        u_int8_t *s, *d;
2528
2529        s = (u_int8_t *)(&ip->ip_src);
2530        d = (u_int8_t *)(&ip->ip_dst);
2531
2532        p = buf;
2533        snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2534        while (p && *p)
2535                p++;
2536        snprintf(p, sizeof(buf) - (p - buf), "src=%u.%u.%u.%u",
2537                s[0], s[1], s[2], s[3]);
2538        while (p && *p)
2539                p++;
2540        snprintf(p, sizeof(buf) - (p - buf), " dst=%u.%u.%u.%u",
2541                d[0], d[1], d[2], d[3]);
2542        while (p && *p)
2543                p++;
2544        snprintf(p, sizeof(buf) - (p - buf), ")");
2545
2546        return buf;
2547}
2548
2549#if INET6
2550const char *
2551ipsec6_logpacketstr(ip6, spi)
2552        struct ip6_hdr *ip6;
2553        u_int32_t spi;
2554{
2555        static char buf[256];
2556        char *p;
2557
2558        p = buf;
2559        snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2560        while (p && *p)
2561                p++;
2562        snprintf(p, sizeof(buf) - (p - buf), "src=%s",
2563                ip6_sprintf(&ip6->ip6_src));
2564        while (p && *p)
2565                p++;
2566        snprintf(p, sizeof(buf) - (p - buf), " dst=%s",
2567                ip6_sprintf(&ip6->ip6_dst));
2568        while (p && *p)
2569                p++;
2570        snprintf(p, sizeof(buf) - (p - buf), ")");
2571
2572        return buf;
2573}
2574#endif /*INET6*/
2575
2576const char *
2577ipsec_logsastr(sav)
2578        struct secasvar *sav;
2579{
2580        static char buf[256];
2581        char *p;
2582        struct secasindex *saidx = &sav->sah->saidx;
2583
2584        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2585
2586        /* validity check */
2587        if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2588                        != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family)
2589                panic("ipsec_logsastr: family mismatched.\n");
2590
2591        p = buf;
2592        snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
2593        while (p && *p)
2594                p++;
2595        if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET) {
2596                u_int8_t *s, *d;
2597                s = (u_int8_t *)&((struct sockaddr_in *)&saidx->src)->sin_addr;
2598                d = (u_int8_t *)&((struct sockaddr_in *)&saidx->dst)->sin_addr;
2599                snprintf(p, sizeof(buf) - (p - buf),
2600                        "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
2601                        s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
2602        }
2603#if INET6
2604        else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
2605                snprintf(p, sizeof(buf) - (p - buf),
2606                        "src=%s",
2607                        ip6_sprintf(&((struct sockaddr_in6 *)&saidx->src)->sin6_addr));
2608                while (p && *p)
2609                        p++;
2610                snprintf(p, sizeof(buf) - (p - buf),
2611                        " dst=%s",
2612                        ip6_sprintf(&((struct sockaddr_in6 *)&saidx->dst)->sin6_addr));
2613        }
2614#endif
2615        while (p && *p)
2616                p++;
2617        snprintf(p, sizeof(buf) - (p - buf), ")");
2618
2619        return buf;
2620}
2621
2622void
2623ipsec_dumpmbuf(m)
2624        struct mbuf *m;
2625{
2626        int totlen;
2627        int i;
2628        u_char *p;
2629
2630        totlen = 0;
2631        printf("---\n");
2632        while (m) {
2633                p = mtod(m, u_char *);
2634                for (i = 0; i < m->m_len; i++) {
2635                        printf("%02x ", p[i]);
2636                        totlen++;
2637                        if (totlen % 16 == 0)
2638                                printf("\n");
2639                }
2640                m = m->m_next;
2641        }
2642        if (totlen % 16 != 0)
2643                printf("\n");
2644        printf("---\n");
2645}
2646
2647#if INET
2648/*
2649 * IPsec output logic for IPv4.
2650 */
2651int
2652ipsec4_output(state, sp, flags)
2653        struct ipsec_output_state *state;
2654        struct secpolicy *sp;
2655        int flags;
2656{
2657        struct ip *ip = NULL;
2658        struct ipsecrequest *isr = NULL;
2659        struct secasindex saidx;
2660        int error;
2661        struct sockaddr_in *dst4;
2662        struct sockaddr_in *sin;
2663
2664        if (!state)
2665                panic("state == NULL in ipsec4_output");
2666        if (!state->m)
2667                panic("state->m == NULL in ipsec4_output");
2668        if (!state->ro)
2669                panic("state->ro == NULL in ipsec4_output");
2670        if (!state->dst)
2671                panic("state->dst == NULL in ipsec4_output");
2672
2673        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2674
2675        KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_START, 0,0,0,0,0);
2676
2677        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2678                printf("ipsec4_output: applyed SP\n");
2679                kdebug_secpolicy(sp));
2680
2681        for (isr = sp->req; isr != NULL; isr = isr->next) {
2682
2683#if 0   /* give up to check restriction of transport mode */
2684        /* XXX but should be checked somewhere */
2685                /*
2686                 * some of the IPsec operation must be performed only in
2687                 * originating case.
2688                 */
2689                if (isr->saidx.mode == IPSEC_MODE_TRANSPORT
2690                 && (flags & IP_FORWARDING))
2691                        continue;
2692#endif
2693
2694                /* make SA index for search proper SA */
2695                ip = mtod(state->m, struct ip *);
2696                bcopy(&isr->saidx, &saidx, sizeof(saidx));
2697                saidx.mode = isr->saidx.mode;
2698                saidx.reqid = isr->saidx.reqid;
2699                sin = (struct sockaddr_in *)&saidx.src;
2700                if (sin->sin_len == 0) {
2701                        sin->sin_len = sizeof(*sin);
2702                        sin->sin_family = AF_INET;
2703                        sin->sin_port = IPSEC_PORT_ANY;
2704                        bcopy(&ip->ip_src, &sin->sin_addr,
2705                            sizeof(sin->sin_addr));
2706                }
2707                sin = (struct sockaddr_in *)&saidx.dst;
2708                if (sin->sin_len == 0) {
2709                        sin->sin_len = sizeof(*sin);
2710                        sin->sin_family = AF_INET;
2711                        sin->sin_port = IPSEC_PORT_ANY;
2712                        bcopy(&ip->ip_dst, &sin->sin_addr,
2713                            sizeof(sin->sin_addr));
2714                }
2715
2716                if ((error = key_checkrequest(isr, &saidx)) != 0) {
2717                        /*
2718                         * IPsec processing is required, but no SA found.
2719                         * I assume that key_acquire() had been called
2720                         * to get/establish the SA. Here I discard
2721                         * this packet because it is responsibility for
2722                         * upper layer to retransmit the packet.
2723                         */
2724                        ipsecstat.out_nosa++;
2725                        goto bad;
2726                }
2727
2728                /* validity check */
2729                if (isr->sav == NULL) {
2730                        switch (ipsec_get_reqlevel(isr)) {
2731                        case IPSEC_LEVEL_USE:
2732                                continue;
2733                        case IPSEC_LEVEL_REQUIRE:
2734                                /* must be not reached here. */
2735                                panic("ipsec4_output: no SA found, but required.");
2736                        }
2737                }
2738
2739                /*
2740                 * If there is no valid SA, we give up to process any
2741                 * more.  In such a case, the SA's status is changed
2742                 * from DYING to DEAD after allocating.  If a packet
2743                 * send to the receiver by dead SA, the receiver can
2744                 * not decode a packet because SA has been dead.
2745                 */
2746                if (isr->sav->state != SADB_SASTATE_MATURE
2747                 && isr->sav->state != SADB_SASTATE_DYING) {
2748                        ipsecstat.out_nosa++;
2749                        error = EINVAL;
2750                        goto bad;
2751                }
2752
2753                /*
2754                 * There may be the case that SA status will be changed when
2755                 * we are refering to one. So calling splsoftnet().
2756                 */
2757
2758                if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2759                        /*
2760                         * build IPsec tunnel.
2761                         */
2762                        /* XXX should be processed with other familiy */
2763                        if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET) {
2764                                ipseclog((LOG_ERR, "ipsec4_output: "
2765                                    "family mismatched between inner and outer spi=%u\n",
2766                                    (u_int32_t)ntohl(isr->sav->spi)));
2767                                error = EAFNOSUPPORT;
2768                                goto bad;
2769                        }
2770
2771                        state->m = ipsec4_splithdr(state->m);
2772                        if (!state->m) {
2773                                error = ENOMEM;
2774                                goto bad;
2775                        }
2776                        error = ipsec4_encapsulate(state->m, isr->sav);
2777                        if (error) {
2778                                state->m = NULL;
2779                                goto bad;
2780                        }
2781                        ip = mtod(state->m, struct ip *);
2782
2783                        state->ro = &isr->sav->sah->sa_route;
2784                        state->dst = (struct sockaddr *)&state->ro->ro_dst;
2785                        dst4 = (struct sockaddr_in *)state->dst;
2786                        if (state->ro->ro_rt
2787                         && ((state->ro->ro_rt->rt_flags & RTF_UP) == 0
2788                          || dst4->sin_addr.s_addr != ip->ip_dst.s_addr)) {
2789                                rtfree(state->ro->ro_rt);
2790                                state->ro->ro_rt = NULL;
2791                        }
2792                        if (state->ro->ro_rt == 0) {
2793                                dst4->sin_family = AF_INET;
2794                                dst4->sin_len = sizeof(*dst4);
2795                                dst4->sin_addr = ip->ip_dst;
2796                                rtalloc(state->ro);
2797                        }
2798                        if (state->ro->ro_rt == 0) {
2799                                ipstat.ips_noroute++;
2800                                error = EHOSTUNREACH;
2801                                goto bad;
2802                        }
2803
2804                        /* adjust state->dst if tunnel endpoint is offlink */
2805                        if (state->ro->ro_rt->rt_flags & RTF_GATEWAY) {
2806                                state->dst = (struct sockaddr *)state->ro->ro_rt->rt_gateway;
2807                                dst4 = (struct sockaddr_in *)state->dst;
2808                        }
2809                }
2810
2811                state->m = ipsec4_splithdr(state->m);
2812                if (!state->m) {
2813                        error = ENOMEM;
2814                        goto bad;
2815                }
2816                switch (isr->saidx.proto) {
2817                case IPPROTO_ESP:
2818#if IPSEC_ESP
2819                        if ((error = esp4_output(state->m, isr)) != 0) {
2820                                state->m = NULL;
2821                                goto bad;
2822                        }
2823                        break;
2824#else
2825                        m_freem(state->m);
2826                        state->m = NULL;
2827                        error = EINVAL;
2828                        goto bad;
2829#endif
2830                case IPPROTO_AH:
2831                        if ((error = ah4_output(state->m, isr)) != 0) {
2832                                state->m = NULL;
2833                                goto bad;
2834                        }
2835                        break;
2836                case IPPROTO_IPCOMP:
2837                        if ((error = ipcomp4_output(state->m, isr)) != 0) {
2838                                state->m = NULL;
2839                                goto bad;
2840                        }
2841                        break;
2842                default:
2843                        ipseclog((LOG_ERR,
2844                            "ipsec4_output: unknown ipsec protocol %d\n",
2845                            isr->saidx.proto));
2846                        m_freem(state->m);
2847                        state->m = NULL;
2848                        error = EINVAL;
2849                        goto bad;
2850                }
2851
2852                if (state->m == 0) {
2853                        error = ENOMEM;
2854                        goto bad;
2855                }
2856                ip = mtod(state->m, struct ip *);
2857        }
2858
2859        KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, 0,0,0,0,0);
2860        return 0;
2861
2862bad:
2863        m_freem(state->m);
2864        state->m = NULL;
2865        KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, error,0,0,0,0);
2866        return error;
2867}
2868#endif
2869
2870#if INET6
2871/*
2872 * IPsec output logic for IPv6, transport mode.
2873 */
2874int
2875ipsec6_output_trans(state, nexthdrp, mprev, sp, flags, tun)
2876        struct ipsec_output_state *state;
2877        u_char *nexthdrp;
2878        struct mbuf *mprev;
2879        struct secpolicy *sp;
2880        int flags;
2881        int *tun;
2882{
2883        struct ip6_hdr *ip6;
2884        struct ipsecrequest *isr = NULL;
2885        struct secasindex saidx;
2886        int error = 0;
2887        int plen;
2888        struct sockaddr_in6 *sin6;
2889
2890        if (!state)
2891                panic("state == NULL in ipsec6_output_trans");
2892        if (!state->m)
2893                panic("state->m == NULL in ipsec6_output_trans");
2894        if (!nexthdrp)
2895                panic("nexthdrp == NULL in ipsec6_output_trans");
2896        if (!mprev)
2897                panic("mprev == NULL in ipsec6_output_trans");
2898        if (!sp)
2899                panic("sp == NULL in ipsec6_output_trans");
2900        if (!tun)
2901                panic("tun == NULL in ipsec6_output_trans");
2902
2903        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2904                printf("ipsec6_output_trans: applyed SP\n");
2905                kdebug_secpolicy(sp));
2906        
2907        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
2908        *tun = 0;
2909        for (isr = sp->req; isr; isr = isr->next) {
2910                if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2911                        /* the rest will be handled by ipsec6_output_tunnel() */
2912                        break;
2913                }
2914
2915                /* make SA index for search proper SA */
2916                ip6 = mtod(state->m, struct ip6_hdr *);
2917                bcopy(&isr->saidx, &saidx, sizeof(saidx));
2918                saidx.mode = isr->saidx.mode;
2919                saidx.reqid = isr->saidx.reqid;
2920                sin6 = (struct sockaddr_in6 *)&saidx.src;
2921                if (sin6->sin6_len == 0) {
2922                        sin6->sin6_len = sizeof(*sin6);
2923                        sin6->sin6_family = AF_INET6;
2924                        sin6->sin6_port = IPSEC_PORT_ANY;
2925                        bcopy(&ip6->ip6_src, &sin6->sin6_addr,
2926                            sizeof(ip6->ip6_src));
2927                        if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
2928                                /* fix scope id for comparing SPD */
2929                                sin6->sin6_addr.s6_addr16[1] = 0;
2930                                sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
2931                        }
2932                }
2933                sin6 = (struct sockaddr_in6 *)&saidx.dst;
2934                if (sin6->sin6_len == 0) {
2935                        sin6->sin6_len = sizeof(*sin6);
2936                        sin6->sin6_family = AF_INET6;
2937                        sin6->sin6_port = IPSEC_PORT_ANY;
2938                        bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
2939                            sizeof(ip6->ip6_dst));
2940                        if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
2941                                /* fix scope id for comparing SPD */
2942                                sin6->sin6_addr.s6_addr16[1] = 0;
2943                                sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
2944                        }
2945                }
2946
2947                if (key_checkrequest(isr, &saidx) == ENOENT) {
2948                        /*
2949                         * IPsec processing is required, but no SA found.
2950                         * I assume that key_acquire() had been called
2951                         * to get/establish the SA. Here I discard
2952                         * this packet because it is responsibility for
2953                         * upper layer to retransmit the packet.
2954                         */
2955                        ipsec6stat.out_nosa++;
2956                        error = ENOENT;
2957
2958                        /*
2959                         * Notify the fact that the packet is discarded
2960                         * to ourselves. I believe this is better than
2961                         * just silently discarding. (jinmei@kame.net)
2962                         * XXX: should we restrict the error to TCP packets?
2963                         * XXX: should we directly notify sockets via
2964                         *      pfctlinputs?
2965                         */
2966                        lck_mtx_unlock(sadb_mutex);
2967                        icmp6_error(state->m, ICMP6_DST_UNREACH,
2968                                    ICMP6_DST_UNREACH_ADMIN, 0);
2969                        lck_mtx_lock(sadb_mutex);
2970                        state->m = NULL; /* icmp6_error freed the mbuf */
2971                        goto bad;
2972                }
2973
2974                /* validity check */
2975                if (isr->sav == NULL) {
2976                        switch (ipsec_get_reqlevel(isr)) {
2977                        case IPSEC_LEVEL_USE:
2978                                continue;
2979                        case IPSEC_LEVEL_REQUIRE:
2980                                /* must be not reached here. */
2981                                panic("ipsec6_output_trans: no SA found, but required.");
2982                        }
2983                }
2984
2985                /*
2986                 * If there is no valid SA, we give up to process.
2987                 * see same place at ipsec4_output().
2988                 */
2989                if (isr->sav->state != SADB_SASTATE_MATURE
2990                 && isr->sav->state != SADB_SASTATE_DYING) {
2991                        ipsec6stat.out_nosa++;
2992                        error = EINVAL;
2993                        goto bad;
2994                }
2995
2996                switch (isr->saidx.proto) {
2997                case IPPROTO_ESP:
2998#if IPSEC_ESP
2999                        error = esp6_output(state->m, nexthdrp, mprev->m_next, isr);
3000#else
3001                        m_freem(state->m);
3002                        error = EINVAL;
3003#endif
3004                        break;
3005                case IPPROTO_AH:
3006                        error = ah6_output(state->m, nexthdrp, mprev->m_next, isr);
3007                        break;
3008                case IPPROTO_IPCOMP:
3009                        error = ipcomp6_output(state->m, nexthdrp, mprev->m_next, isr);
3010                        break;
3011                default:
3012                        ipseclog((LOG_ERR, "ipsec6_output_trans: "
3013                            "unknown ipsec protocol %d\n", isr->saidx.proto));
3014                        m_freem(state->m);
3015                        ipsec6stat.out_inval++;
3016                        error = EINVAL;
3017                        break;
3018                }
3019                if (error) {
3020                        state->m = NULL;
3021                        goto bad;
3022                }
3023                plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3024                if (plen > IPV6_MAXPACKET) {
3025                        ipseclog((LOG_ERR, "ipsec6_output_trans: "
3026                            "IPsec with IPv6 jumbogram is not supported\n"));
3027                        ipsec6stat.out_inval++;
3028                        error = EINVAL; /*XXX*/
3029                        goto bad;
3030                }
3031                ip6 = mtod(state->m, struct ip6_hdr *);
3032                ip6->ip6_plen = htons(plen);
3033        }
3034
3035        /* if we have more to go, we need a tunnel mode processing */
3036        if (isr != NULL)
3037                *tun = 1;
3038
3039        return 0;
3040
3041bad:
3042        m_freem(state->m);
3043        state->m = NULL;
3044        return error;
3045}
3046
3047/*
3048 * IPsec output logic for IPv6, tunnel mode.
3049 */
3050int
3051ipsec6_output_tunnel(state, sp, flags)
3052        struct ipsec_output_state *state;
3053        struct secpolicy *sp;
3054        int flags;
3055{
3056        struct ip6_hdr *ip6;
3057        struct ipsecrequest *isr = NULL;
3058        struct secasindex saidx;
3059        int error = 0;
3060        int plen;
3061        struct sockaddr_in6* dst6;
3062
3063        if (!state)
3064                panic("state == NULL in ipsec6_output_tunnel");
3065        if (!state->m)
3066                panic("state->m == NULL in ipsec6_output_tunnel");
3067        if (!sp)
3068                panic("sp == NULL in ipsec6_output_tunnel");
3069
3070        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
3071
3072        KEYDEBUG(KEYDEBUG_IPSEC_DATA,
3073                printf("ipsec6_output_tunnel: applyed SP\n");
3074                kdebug_secpolicy(sp));
3075
3076        /*
3077         * transport mode ipsec (before the 1st tunnel mode) is already
3078         * processed by ipsec6_output_trans().
3079         */
3080        for (isr = sp->req; isr; isr = isr->next) {
3081                if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
3082                        break;
3083        }
3084
3085        for (/* already initialized */; isr; isr = isr->next) {
3086                if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3087                        /* When tunnel mode, SA peers must be specified. */
3088                        bcopy(&isr->saidx, &saidx, sizeof(saidx));
3089                } else {
3090                        /* make SA index to look for a proper SA */
3091                        struct sockaddr_in6 *sin6;
3092
3093                        bzero(&saidx, sizeof(saidx));
3094                        saidx.proto = isr->saidx.proto;
3095                        saidx.mode = isr->saidx.mode;
3096                        saidx.reqid = isr->saidx.reqid;
3097
3098                        ip6 = mtod(state->m, struct ip6_hdr *);
3099                        sin6 = (struct sockaddr_in6 *)&saidx.src;
3100                        if (sin6->sin6_len == 0) {
3101                                sin6->sin6_len = sizeof(*sin6);
3102                                sin6->sin6_family = AF_INET6;
3103                                sin6->sin6_port = IPSEC_PORT_ANY;
3104                                bcopy(&ip6->ip6_src, &sin6->sin6_addr,
3105                                    sizeof(ip6->ip6_src));
3106                                if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
3107                                        /* fix scope id for comparing SPD */
3108                                        sin6->sin6_addr.s6_addr16[1] = 0;
3109                                        sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
3110                                }
3111                        }
3112                        sin6 = (struct sockaddr_in6 *)&saidx.dst;
3113                        if (sin6->sin6_len == 0) {
3114                                sin6->sin6_len = sizeof(*sin6);
3115                                sin6->sin6_family = AF_INET6;
3116                                sin6->sin6_port = IPSEC_PORT_ANY;
3117                                bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
3118                                    sizeof(ip6->ip6_dst));
3119                                if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
3120                                        /* fix scope id for comparing SPD */
3121                                        sin6->sin6_addr.s6_addr16[1] = 0;
3122                                        sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
3123                                }
3124                        }
3125                }
3126
3127                if (key_checkrequest(isr, &saidx) == ENOENT) {
3128                        /*
3129                         * IPsec processing is required, but no SA found.
3130                         * I assume that key_acquire() had been called
3131                         * to get/establish the SA. Here I discard
3132                         * this packet because it is responsibility for
3133                         * upper layer to retransmit the packet.
3134                         */
3135                        ipsec6stat.out_nosa++;
3136                        error = ENOENT;
3137                        goto bad;
3138                }
3139
3140                /* validity check */
3141                if (isr->sav == NULL) {
3142                        switch (ipsec_get_reqlevel(isr)) {
3143                        case IPSEC_LEVEL_USE:
3144                                continue;
3145                        case IPSEC_LEVEL_REQUIRE:
3146                                /* must be not reached here. */
3147                                panic("ipsec6_output_tunnel: no SA found, but required.");
3148                        }
3149                }
3150
3151                /*
3152                 * If there is no valid SA, we give up to process.
3153                 * see same place at ipsec4_output().
3154                 */
3155                if (isr->sav->state != SADB_SASTATE_MATURE
3156                 && isr->sav->state != SADB_SASTATE_DYING) {
3157                        ipsec6stat.out_nosa++;
3158                        error = EINVAL;
3159                        goto bad;
3160                }
3161
3162                /*
3163                 * There may be the case that SA status will be changed when
3164                 * we are refering to one. So calling splsoftnet().
3165                 */
3166
3167                if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3168                        /*
3169                         * build IPsec tunnel.
3170                         */
3171                        /* XXX should be processed with other familiy */
3172                        if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET6) {
3173                                ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3174                                    "family mismatched between inner and outer, spi=%u\n",
3175                                    (u_int32_t)ntohl(isr->sav->spi)));
3176                                ipsec6stat.out_inval++;
3177                                error = EAFNOSUPPORT;
3178                                goto bad;
3179                        }
3180
3181                        state->m = ipsec6_splithdr(state->m);
3182                        if (!state->m) {
3183                                ipsec6stat.out_nomem++;
3184                                error = ENOMEM;
3185                                goto bad;
3186                        }
3187                        error = ipsec6_encapsulate(state->m, isr->sav);
3188                        if (error) {
3189                                state->m = 0;
3190                                goto bad;
3191                        }
3192                        ip6 = mtod(state->m, struct ip6_hdr *);
3193
3194                        state->ro = &isr->sav->sah->sa_route;
3195                        state->dst = (struct sockaddr *)&state->ro->ro_dst;
3196                        dst6 = (struct sockaddr_in6 *)state->dst;
3197                        if (state->ro->ro_rt
3198                         && ((state->ro->ro_rt->rt_flags & RTF_UP) == 0
3199                          || !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))) {
3200                                rtfree(state->ro->ro_rt);
3201                                state->ro->ro_rt = NULL;
3202                        }
3203                        if (state->ro->ro_rt == 0) {
3204                                bzero(dst6, sizeof(*dst6));
3205                                dst6->sin6_family = AF_INET6;
3206                                dst6->sin6_len = sizeof(*dst6);
3207                                dst6->sin6_addr = ip6->ip6_dst;
3208                                rtalloc(state->ro);
3209                        }
3210                        if (state->ro->ro_rt == 0) {
3211                                ip6stat.ip6s_noroute++;
3212                                ipsec6stat.out_noroute++;
3213                                error = EHOSTUNREACH;
3214                                goto bad;
3215                        }
3216
3217                        /* adjust state->dst if tunnel endpoint is offlink */
3218                        if (state->ro->ro_rt->rt_flags & RTF_GATEWAY) {
3219                                state->dst = (struct sockaddr *)state->ro->ro_rt->rt_gateway;
3220                                dst6 = (struct sockaddr_in6 *)state->dst;
3221                        }
3222                }
3223
3224                state->m = ipsec6_splithdr(state->m);
3225                if (!state->m) {
3226                        ipsec6stat.out_nomem++;
3227                        error = ENOMEM;
3228                        goto bad;
3229                }
3230                ip6 = mtod(state->m, struct ip6_hdr *);
3231                switch (isr->saidx.proto) {
3232                case IPPROTO_ESP:
3233#if IPSEC_ESP
3234                        error = esp6_output(state->m, &ip6->ip6_nxt, state->m->m_next, isr);
3235#else
3236                        m_freem(state->m);
3237                        error = EINVAL;
3238#endif
3239                        break;
3240                case IPPROTO_AH:
3241                        error = ah6_output(state->m, &ip6->ip6_nxt, state->m->m_next, isr);
3242                        break;
3243                case IPPROTO_IPCOMP:
3244                        /* XXX code should be here */
3245                        /*FALLTHROUGH*/
3246                default:
3247                        ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3248                            "unknown ipsec protocol %d\n", isr->saidx.proto));
3249                        m_freem(state->m);
3250                        ipsec6stat.out_inval++;
3251                        error = EINVAL;
3252                        break;
3253                }
3254                if (error) {
3255                        state->m = NULL;
3256                        goto bad;
3257                }
3258                plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3259                if (plen > IPV6_MAXPACKET) {
3260                        ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3261                            "IPsec with IPv6 jumbogram is not supported\n"));
3262                        ipsec6stat.out_inval++;
3263                        error = EINVAL; /*XXX*/
3264                        goto bad;
3265                }
3266                ip6 = mtod(state->m, struct ip6_hdr *);
3267                ip6->ip6_plen = htons(plen);
3268        }
3269
3270        return 0;
3271
3272bad:
3273        m_freem(state->m);
3274        state->m = NULL;
3275        return error;
3276}
3277#endif /*INET6*/
3278
3279#if INET
3280/*
3281 * Chop IP header and option off from the payload.
3282 */
3283static struct mbuf *
3284ipsec4_splithdr(m)
3285        struct mbuf *m;
3286{
3287        struct mbuf *mh;
3288        struct ip *ip;
3289        int hlen;
3290
3291        if (m->m_len < sizeof(struct ip))
3292                panic("ipsec4_splithdr: first mbuf too short");
3293        ip = mtod(m, struct ip *);
3294#ifdef _IP_VHL
3295        hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
3296#else
3297        hlen = ip->ip_hl << 2;
3298#endif
3299        if (m->m_len > hlen) {
3300                MGETHDR(mh, M_DONTWAIT, MT_HEADER);
3301                if (!mh) {
3302                        m_freem(m);
3303                        return NULL;
3304                }
3305                M_COPY_PKTHDR(mh, m);
3306                MH_ALIGN(mh, hlen);
3307                m->m_flags &= ~M_PKTHDR;
3308                m->m_len -= hlen;
3309                m->m_data += hlen;
3310                mh->m_next = m;
3311                m = mh;
3312                m->m_len = hlen;
3313                bcopy((caddr_t)ip, mtod(m, caddr_t), hlen);
3314        } else if (m->m_len < hlen) {
3315                m = m_pullup(m, hlen);
3316                if (!m)
3317                        return NULL;
3318        }
3319        return m;
3320}
3321#endif
3322
3323#if INET6
3324static struct mbuf *
3325ipsec6_splithdr(m)
3326        struct mbuf *m;
3327{
3328        struct mbuf *mh;
3329        struct ip6_hdr *ip6;
3330        int hlen;
3331
3332        if (m->m_len < sizeof(struct ip6_hdr))
3333                panic("ipsec6_splithdr: first mbuf too short");
3334        ip6 = mtod(m, struct ip6_hdr *);
3335        hlen = sizeof(struct ip6_hdr);
3336        if (m->m_len > hlen) {
3337                MGETHDR(mh, M_DONTWAIT, MT_HEADER);
3338                if (!mh) {
3339                        m_freem(m);
3340                        return NULL;
3341                }
3342                M_COPY_PKTHDR(mh, m);
3343                MH_ALIGN(mh, hlen);
3344                m->m_flags &= ~M_PKTHDR;
3345                m->m_len -= hlen;
3346                m->m_data += hlen;
3347                mh->m_next = m;
3348                m = mh;
3349                m->m_len = hlen;
3350                bcopy((caddr_t)ip6, mtod(m, caddr_t), hlen);
3351        } else if (m->m_len < hlen) {
3352                m = m_pullup(m, hlen);
3353                if (!m)
3354                        return NULL;
3355        }
3356        return m;
3357}
3358#endif
3359
3360/* validate inbound IPsec tunnel packet. */
3361int
3362ipsec4_tunnel_validate(m, off, nxt0, sav)
3363        struct mbuf *m;         /* no pullup permitted, m->m_len >= ip */
3364        int off;
3365        u_int nxt0;
3366        struct secasvar *sav;
3367{
3368        u_int8_t nxt = nxt0 & 0xff;
3369        struct sockaddr_in *sin;
3370        struct sockaddr_in osrc, odst, isrc, idst;
3371        int hlen;
3372        struct secpolicy *sp;
3373        struct ip *oip;
3374
3375        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
3376
3377#if DIAGNOSTIC
3378        if (m->m_len < sizeof(struct ip))
3379                panic("too short mbuf on ipsec4_tunnel_validate");
3380#endif
3381        if (nxt != IPPROTO_IPV4)
3382                return 0;
3383        if (m->m_pkthdr.len < off + sizeof(struct ip))
3384                return 0;
3385        /* do not decapsulate if the SA is for transport mode only */
3386        if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3387                return 0;
3388
3389        oip = mtod(m, struct ip *);
3390#ifdef _IP_VHL
3391        hlen = _IP_VHL_HL(oip->ip_vhl) << 2;
3392#else
3393        hlen = oip->ip_hl << 2;
3394#endif
3395        if (hlen != sizeof(struct ip))
3396                return 0;
3397
3398        /* AF_INET6 should be supported, but at this moment we don't. */
3399        sin = (struct sockaddr_in *)&sav->sah->saidx.dst;
3400        if (sin->sin_family != AF_INET)
3401                return 0;
3402        if (bcmp(&oip->ip_dst, &sin->sin_addr, sizeof(oip->ip_dst)) != 0)
3403                return 0;
3404
3405        /* XXX slow */
3406        bzero(&osrc, sizeof(osrc));
3407        bzero(&odst, sizeof(odst));
3408        bzero(&isrc, sizeof(isrc));
3409        bzero(&idst, sizeof(idst));
3410        osrc.sin_family = odst.sin_family = isrc.sin_family = idst.sin_family = 
3411            AF_INET;
3412        osrc.sin_len = odst.sin_len = isrc.sin_len = idst.sin_len = 
3413            sizeof(struct sockaddr_in);
3414        osrc.sin_addr = oip->ip_src;
3415        odst.sin_addr = oip->ip_dst;
3416        m_copydata(m, off + offsetof(struct ip, ip_src), sizeof(isrc.sin_addr),
3417            (caddr_t)&isrc.sin_addr);
3418        m_copydata(m, off + offsetof(struct ip, ip_dst), sizeof(idst.sin_addr),
3419            (caddr_t)&idst.sin_addr);
3420
3421        /*
3422         * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
3423         * - if the inner destination is multicast address, there can be
3424         *   multiple permissible inner source address.  implementation
3425         *   may want to skip verification of inner source address against
3426         *   SPD selector.
3427         * - if the inner protocol is ICMP, the packet may be an error report
3428         *   from routers on the other side of the VPN cloud (R in the
3429         *   following diagram).  in this case, we cannot verify inner source
3430         *   address against SPD selector.
3431         *      me -- gw === gw -- R -- you
3432         *
3433         * we consider the first bullet to be users responsibility on SPD entry
3434         * configuration (if you need to encrypt multicast traffic, set
3435         * the source range of SPD selector to 0.0.0.0/0, or have explicit
3436         * address ranges for possible senders).
3437         * the second bullet is not taken care of (yet).
3438         *
3439         * therefore, we do not do anything special about inner source.
3440         */
3441
3442        sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
3443            (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
3444        if (!sp) {
3445                return 0;
3446        }
3447        key_freesp(sp);
3448
3449        return 1;
3450}
3451
3452#if INET6
3453/* validate inbound IPsec tunnel packet. */
3454int
3455ipsec6_tunnel_validate(m, off, nxt0, sav)
3456        struct mbuf *m;         /* no pullup permitted, m->m_len >= ip */
3457        int off;
3458        u_int nxt0;
3459        struct secasvar *sav;
3460{
3461        u_int8_t nxt = nxt0 & 0xff;
3462        struct sockaddr_in6 *sin6;
3463        struct sockaddr_in6 osrc, odst, isrc, idst;
3464        struct secpolicy *sp;
3465        struct ip6_hdr *oip6;
3466
3467        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
3468
3469#if DIAGNOSTIC
3470        if (m->m_len < sizeof(struct ip6_hdr))
3471                panic("too short mbuf on ipsec6_tunnel_validate");
3472#endif
3473        if (nxt != IPPROTO_IPV6)
3474                return 0;
3475        if (m->m_pkthdr.len < off + sizeof(struct ip6_hdr))
3476                return 0;
3477        /* do not decapsulate if the SA is for transport mode only */
3478        if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3479                return 0;
3480
3481        oip6 = mtod(m, struct ip6_hdr *);
3482        /* AF_INET should be supported, but at this moment we don't. */
3483        sin6 = (struct sockaddr_in6 *)&sav->sah->saidx.dst;
3484        if (sin6->sin6_family != AF_INET6)
3485                return 0;
3486        if (!IN6_ARE_ADDR_EQUAL(&oip6->ip6_dst, &sin6->sin6_addr))
3487                return 0;
3488
3489        /* XXX slow */
3490        bzero(&osrc, sizeof(osrc));
3491        bzero(&odst, sizeof(odst));
3492        bzero(&isrc, sizeof(isrc));
3493        bzero(&idst, sizeof(idst));
3494        osrc.sin6_family = odst.sin6_family = isrc.sin6_family =
3495            idst.sin6_family = AF_INET6;
3496        osrc.sin6_len = odst.sin6_len = isrc.sin6_len = idst.sin6_len = 
3497            sizeof(struct sockaddr_in6);
3498        osrc.sin6_addr = oip6->ip6_src;
3499        odst.sin6_addr = oip6->ip6_dst;
3500        m_copydata(m, off + offsetof(struct ip6_hdr, ip6_src),
3501            sizeof(isrc.sin6_addr), (caddr_t)&isrc.sin6_addr);
3502        m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
3503            sizeof(idst.sin6_addr), (caddr_t)&idst.sin6_addr);
3504
3505        /*
3506         * regarding to inner source address validation, see a long comment
3507         * in ipsec4_tunnel_validate.
3508         */
3509
3510        sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
3511            (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
3512        /*
3513         * when there is no suitable inbound policy for the packet of the ipsec
3514         * tunnel mode, the kernel never decapsulate the tunneled packet
3515         * as the ipsec tunnel mode even when the system wide policy is "none".
3516         * then the kernel leaves the generic tunnel module to process this
3517         * packet.  if there is no rule of the generic tunnel, the packet
3518         * is rejected and the statistics will be counted up.
3519         */
3520        if (!sp)
3521                return 0;
3522        key_freesp(sp);
3523
3524        return 1;
3525}
3526#endif
3527
3528/*
3529 * Make a mbuf chain for encryption.
3530 * If the original mbuf chain contains a mbuf with a cluster,
3531 * allocate a new cluster and copy the data to the new cluster.
3532 * XXX: this hack is inefficient, but is necessary to handle cases
3533 * of TCP retransmission...
3534 */
3535struct mbuf *
3536ipsec_copypkt(m)
3537        struct mbuf *m;
3538{
3539        struct mbuf *n, **mpp, *mnew;
3540
3541        for (n = m, mpp = &m; n; n = n->m_next) {
3542                if (n->m_flags & M_EXT) {
3543                        /*
3544                         * Make a copy only if there are more than one references
3545                         * to the cluster.
3546                         * XXX: is this approach effective?
3547                         */
3548                        if (
3549                                n->m_ext.ext_free ||
3550                                m_mclhasreference(n)
3551                            )
3552                        {
3553                                int remain, copied;
3554                                struct mbuf *mm;
3555
3556                                if (n->m_flags & M_PKTHDR) {
3557                                        MGETHDR(mnew, M_DONTWAIT, MT_HEADER);
3558                                        if (mnew == NULL)
3559                                                goto fail;
3560                                        mnew->m_pkthdr = n->m_pkthdr;
3561#if 0
3562                                        if (n->m_pkthdr.aux) {
3563                                                mnew->m_pkthdr.aux =
3564                                                    m_copym(n->m_pkthdr.aux,
3565                                                    0, M_COPYALL, M_DONTWAIT);
3566                                        }
3567#endif
3568                                        M_COPY_PKTHDR(mnew, n);
3569                                        mnew->m_flags = n->m_flags & M_COPYFLAGS;
3570                                }
3571                                else {
3572                                        MGET(mnew, M_DONTWAIT, MT_DATA);
3573                                        if (mnew == NULL)
3574                                                goto fail;
3575                                }
3576                                mnew->m_len = 0;
3577                                mm = mnew;
3578
3579                                /*
3580                                 * Copy data. If we don't have enough space to
3581                                 * store the whole data, allocate a cluster
3582                                 * or additional mbufs.
3583                                 * XXX: we don't use m_copyback(), since the
3584                                 * function does not use clusters and thus is
3585                                 * inefficient.
3586                                 */
3587                                remain = n->m_len;
3588                                copied = 0;
3589                                while (1) {
3590                                        int len;
3591                                        struct mbuf *mn;
3592
3593                                        if (remain <= (mm->m_flags & M_PKTHDR ? MHLEN : MLEN))
3594                                                len = remain;
3595                                        else { /* allocate a cluster */
3596                                                MCLGET(mm, M_DONTWAIT);
3597                                                if (!(mm->m_flags & M_EXT)) {
3598                                                        m_free(mm);
3599                                                        goto fail;
3600                                                }
3601                                                len = remain < MCLBYTES ?
3602                                                        remain : MCLBYTES;
3603                                        }
3604
3605                                        bcopy(n->m_data + copied, mm->m_data,
3606                                              len);
3607
3608                                        copied += len;
3609                                        remain -= len;
3610                                        mm->m_len = len;
3611
3612                                        if (remain <= 0) /* completed? */
3613                                                break;
3614
3615                                        /* need another mbuf */
3616                                        MGETHDR(mn, M_DONTWAIT, MT_HEADER);
3617                                        if (mn == NULL)
3618                                                goto fail;
3619                                        mn->m_pkthdr.rcvif = NULL;
3620                                        mm->m_next = mn;
3621                                        mm = mn;
3622                                }
3623
3624                                /* adjust chain */
3625                                mm->m_next = m_free(n);
3626                                n = mm;
3627                                *mpp = mnew;
3628                                mpp = &n->m_next;
3629
3630                                continue;
3631                        }
3632                }
3633                *mpp = n;
3634                mpp = &n->m_next;
3635        }
3636
3637        return(m);
3638  fail:
3639        m_freem(m);
3640        return(NULL);
3641}
3642
3643static struct mbuf *
3644ipsec_addaux(m)
3645        struct mbuf *m;
3646{
3647        struct mbuf *n;
3648
3649        n = m_aux_find(m, AF_INET, IPPROTO_ESP);
3650        if (!n)
3651                n = m_aux_add(m, AF_INET, IPPROTO_ESP);
3652        if (!n)
3653                return n;       /* ENOBUFS */
3654        n->m_len = sizeof(struct socket *);
3655        bzero(mtod(n, void *), n->m_len);
3656        return n;
3657}
3658
3659static struct mbuf *
3660ipsec_findaux(m)
3661        struct mbuf *m;
3662{
3663        struct mbuf *n;
3664
3665        n = m_aux_find(m, AF_INET, IPPROTO_ESP);
3666#if DIAGNOSTIC
3667        if (n && n->m_len < sizeof(struct socket *))
3668                panic("invalid ipsec m_aux");
3669#endif
3670        return n;
3671}
3672
3673void
3674ipsec_delaux(m)
3675        struct mbuf *m;
3676{
3677        struct mbuf *n;
3678
3679        n = m_aux_find(m, AF_INET, IPPROTO_ESP);
3680        if (n)
3681                m_aux_delete(m, n);
3682}
3683
3684/* if the aux buffer is unnecessary, nuke it. */
3685static void
3686ipsec_optaux(m, n)
3687        struct mbuf *m;
3688        struct mbuf *n;
3689{
3690
3691        if (!n)
3692                return;
3693        if (n->m_len == sizeof(struct socket *) && !*mtod(n, struct socket **))
3694                ipsec_delaux(m);
3695}
3696
3697int
3698ipsec_setsocket(m, so)
3699        struct mbuf *m;
3700        struct socket *so;
3701{
3702        struct mbuf *n;
3703
3704        /* if so == NULL, don't insist on getting the aux mbuf */
3705        if (so) {
3706                n = ipsec_addaux(m);
3707                if (!n)
3708                        return ENOBUFS;
3709        } else
3710                n = ipsec_findaux(m);
3711        if (n && n->m_len >= sizeof(struct socket *))
3712                *mtod(n, struct socket **) = so;
3713        ipsec_optaux(m, n);
3714        return 0;
3715}
3716
3717struct socket *
3718ipsec_getsocket(m)
3719        struct mbuf *m;
3720{
3721        struct mbuf *n;
3722
3723        n = ipsec_findaux(m);
3724        if (n && n->m_len >= sizeof(struct socket *))
3725                return *mtod(n, struct socket **);
3726        else
3727                return NULL;
3728}
3729
3730int
3731ipsec_addhist(m, proto, spi)
3732        struct mbuf *m;
3733        int proto;
3734        u_int32_t spi;
3735{
3736        struct mbuf *n;
3737        struct ipsec_history *p;
3738
3739        n = ipsec_addaux(m);
3740        if (!n)
3741                return ENOBUFS;
3742        if (M_TRAILINGSPACE(n) < sizeof(*p))
3743                return ENOSPC;  /* XXX */
3744        p = (struct ipsec_history *)(mtod(n, caddr_t) + n->m_len);
3745        n->m_len += sizeof(*p);
3746        bzero(p, sizeof(*p));
3747        p->ih_proto = proto;
3748        p->ih_spi = spi;
3749        return 0;
3750}
3751
3752struct ipsec_history *
3753ipsec_gethist(m, lenp)
3754        struct mbuf *m;
3755        int *lenp;
3756{
3757        struct mbuf *n;
3758        int l;
3759
3760        n = ipsec_findaux(m);
3761        if (!n)
3762                return NULL;
3763        l = n->m_len;
3764        if (sizeof(struct socket *) > l)
3765                return NULL;
3766        if ((l - sizeof(struct socket *)) % sizeof(struct ipsec_history))
3767                return NULL;
3768        /* XXX does it make more sense to divide by sizeof(ipsec_history)? */
3769        if (lenp)
3770                *lenp = l - sizeof(struct socket *);
3771        return (struct ipsec_history *)
3772            (mtod(n, caddr_t) + sizeof(struct socket *));
3773}
3774
3775void
3776ipsec_clearhist(m)
3777        struct mbuf *m;
3778{
3779        struct mbuf *n;
3780
3781        n = ipsec_findaux(m);
3782        if ((n) && n->m_len > sizeof(struct socket *))
3783                n->m_len = sizeof(struct socket *);
3784        ipsec_optaux(m, n);
3785}
3786
3787__private_extern__ void
3788ipsec_send_natt_keepalive(
3789        struct secasvar *sav)
3790{
3791        struct mbuf     *m;
3792        struct udphdr *uh;
3793        struct ip *ip;
3794        int error;
3795
3796        if ((esp_udp_encap_port & 0xFFFF) == 0 || sav->remote_ike_port == 0) return;
3797        
3798        lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
3799
3800        m = m_gethdr(M_NOWAIT, MT_DATA);
3801        if (m == NULL) return;
3802        
3803        /*
3804         * Create a UDP packet complete with IP header.
3805         * We must do this because UDP output requires
3806         * an inpcb which we don't have. UDP packet
3807         * contains one byte payload. The byte is set
3808         * to 0xFF.
3809         */
3810        ip = (struct ip*)m_mtod(m);
3811        uh = (struct udphdr*)((char*)m_mtod(m) + sizeof(struct ip));
3812        m->m_len = sizeof(struct udpiphdr) + 1;
3813        bzero(m_mtod(m), m->m_len);
3814        m->m_pkthdr.len = m->m_len;
3815
3816        ip->ip_len = m->m_len;
3817        ip->ip_ttl = ip_defttl;
3818        ip->ip_p = IPPROTO_UDP;
3819        ip->ip_src = ((struct sockaddr_in*)&sav->sah->saidx.src)->sin_addr;
3820        ip->ip_dst = ((struct sockaddr_in*)&sav->sah->saidx.dst)->sin_addr;
3821        uh->uh_sport = htons((u_short)esp_udp_encap_port);
3822        uh->uh_dport = htons(sav->remote_ike_port);
3823        uh->uh_ulen = htons(1 + sizeof(struct udphdr));
3824        uh->uh_sum = 0;
3825        *(u_int8_t*)((char*)m_mtod(m) + sizeof(struct ip) + sizeof(struct udphdr)) = 0xFF;
3826        
3827        lck_mtx_unlock(sadb_mutex);
3828        error = ip_output(m, NULL, &sav->sah->sa_route, IP_NOIPSEC, NULL);
3829        lck_mtx_lock(sadb_mutex);
3830        if (error == 0)
3831                sav->natt_last_activity = natt_now;
3832
3833}
3834
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.