File:  [DragonFly] / src / sys / netinet6 / ipsec.c
Revision 1.5: download - view: text, annotated - select for diffs
Sat Feb 14 21:15:31 2004 UTC (10 years, 8 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Move <machine/in_cksum.h> to <sys/in_cksum.h>.  This file is now platform
independant.  If we want to add extreme machine specialization later on
then sys/in_cksum.h will #include machine/in_cksum.h.

Move i386/i386/in_cksum.c to netinet/in_cksum.c.  Note that netinet/in_cksum.c
already existed but was not used by the build system at all.  The move
overwrites it.  The new in_cksum.c is a portable, complete rewrite which
references core assembly (procedure call) to do 32-bit-aligned work.  See
also i386/i386/in_cksum2.s.

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