File:  [DragonFly] / src / sys / netinet6 / ipsec.c
Revision 1.4: download - view: text, annotated - select for diffs
Sat Aug 23 11:02:45 2003 UTC (11 years ago) by rob
Branches: MAIN
CVS tags: HEAD
well, if netproto doesnt need old prototypes inet6 doesnt either

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