File:  [DragonFly] / src / sys / netproto / ipsec / ipsec.c
Revision 1.4: download - view: text, annotated - select for diffs
Sat Aug 23 10:06:23 2003 UTC (10 years, 11 months ago) by rob
Branches: MAIN
CVS tags: HEAD
Do you think /sys/netproto needs to use __P() prototypes?

I don't.

    1: /*	$FreeBSD: src/sys/netipsec/ipsec.c,v 1.2.2.1 2003/01/24 05:11:35 sam Exp $	*/
    2: /*	$DragonFly: src/sys/netproto/ipsec/ipsec.c,v 1.4 2003/08/23 10:06:23 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/tcp.h>
   68: #include <netinet/udp.h>
   69: 
   70: #include <netinet/ip6.h>
   71: #ifdef INET6
   72: #include <netinet6/ip6_var.h>
   73: #endif
   74: #include <netinet/in_pcb.h>
   75: #ifdef INET6
   76: #include <netinet/icmp6.h>
   77: #endif
   78: 
   79: #include "ipsec.h"
   80: #ifdef INET6
   81: #include "ipsec6.h"
   82: #endif
   83: #include "ah_var.h"
   84: #include "esp_var.h"
   85: #include "ipcomp.h"		/*XXX*/
   86: #include "ipcomp_var.h"
   87: 
   88: #include "key.h"
   89: #include "keydb.h"
   90: #include "key_debug.h"
   91: 
   92: #include "xform.h"
   93: 
   94: #include <machine/in_cksum.h>
   95: 
   96: #include <net/net_osdep.h>
   97: 
   98: #ifdef IPSEC_DEBUG
   99: int ipsec_debug = 1;
  100: #else
  101: int ipsec_debug = 0;
  102: #endif
  103: 
  104: /* NB: name changed so netstat doesn't use it */
  105: struct newipsecstat newipsecstat;
  106: int ip4_ah_offsetmask = 0;	/* maybe IP_DF? */
  107: int ip4_ipsec_dfbit = 0;	/* DF bit on encap. 0: clear 1: set 2: copy */
  108: int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
  109: int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
  110: int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
  111: int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
  112: struct secpolicy ip4_def_policy;
  113: int ip4_ipsec_ecn = 0;		/* ECN ignore(-1)/forbidden(0)/allowed(1) */
  114: int ip4_esp_randpad = -1;
  115: /*
  116:  * Crypto support requirements:
  117:  *
  118:  *  1	require hardware support
  119:  * -1	require software support
  120:  *  0	take anything
  121:  */
  122: int	crypto_support = 0;
  123: 
  124: SYSCTL_DECL(_net_inet_ipsec);
  125: 
  126: /* net.inet.ipsec */
  127: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
  128: 	def_policy, CTLFLAG_RW,	&ip4_def_policy.policy,	0, "");
  129: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
  130: 	CTLFLAG_RW, &ip4_esp_trans_deflev,	0, "");
  131: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
  132: 	CTLFLAG_RW, &ip4_esp_net_deflev,	0, "");
  133: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
  134: 	CTLFLAG_RW, &ip4_ah_trans_deflev,	0, "");
  135: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
  136: 	CTLFLAG_RW, &ip4_ah_net_deflev,	0, "");
  137: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
  138: 	ah_cleartos, CTLFLAG_RW,	&ah_cleartos,	0, "");
  139: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
  140: 	ah_offsetmask, CTLFLAG_RW,	&ip4_ah_offsetmask,	0, "");
  141: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
  142: 	dfbit, CTLFLAG_RW,	&ip4_ipsec_dfbit,	0, "");
  143: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
  144: 	ecn, CTLFLAG_RW,	&ip4_ipsec_ecn,	0, "");
  145: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
  146: 	debug, CTLFLAG_RW,	&ipsec_debug,	0, "");
  147: SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
  148: 	esp_randpad, CTLFLAG_RW,	&ip4_esp_randpad,	0, "");
  149: SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
  150: 	crypto_support,	CTLFLAG_RW,	&crypto_support,0, "");
  151: SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
  152: 	ipsecstats,	CTLFLAG_RD,	&newipsecstat,	newipsecstat, "");
  153: 
  154: #ifdef INET6
  155: int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
  156: int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
  157: int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
  158: int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
  159: int ip6_ipsec_ecn = 0;		/* ECN ignore(-1)/forbidden(0)/allowed(1) */
  160: int ip6_esp_randpad = -1;
  161: 
  162: SYSCTL_DECL(_net_inet6_ipsec6);
  163: 
  164: /* net.inet6.ipsec6 */
  165: #ifdef COMPAT_KAME
  166: SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
  167: 	0,0, compat_ipsecstats_sysctl, "S", "");
  168: #endif /* COMPAT_KAME */
  169: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
  170: 	def_policy, CTLFLAG_RW,	&ip4_def_policy.policy,	0, "");
  171: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
  172: 	CTLFLAG_RW, &ip6_esp_trans_deflev,	0, "");
  173: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
  174: 	CTLFLAG_RW, &ip6_esp_net_deflev,	0, "");
  175: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
  176: 	CTLFLAG_RW, &ip6_ah_trans_deflev,	0, "");
  177: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
  178: 	CTLFLAG_RW, &ip6_ah_net_deflev,	0, "");
  179: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
  180: 	ecn, CTLFLAG_RW,	&ip6_ipsec_ecn,	0, "");
  181: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
  182: 	debug, CTLFLAG_RW,	&ipsec_debug,	0, "");
  183: SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
  184: 	esp_randpad, CTLFLAG_RW,	&ip6_esp_randpad,	0, "");
  185: #endif /* INET6 */
  186: 
  187: static int ipsec4_setspidx_inpcb (struct mbuf *, struct inpcb *pcb);
  188: #ifdef INET6
  189: static int ipsec6_setspidx_in6pcb (struct mbuf *, struct in6pcb *pcb);
  190: #endif
  191: static int ipsec_setspidx (struct mbuf *, struct secpolicyindex *, int);
  192: static void ipsec4_get_ulp (struct mbuf *m, struct secpolicyindex *, int);
  193: static int ipsec4_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
  194: #ifdef INET6
  195: static void ipsec6_get_ulp (struct mbuf *m, struct secpolicyindex *, int);
  196: static int ipsec6_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
  197: #endif
  198: static void ipsec_delpcbpolicy (struct inpcbpolicy *);
  199: static struct secpolicy *ipsec_deepcopy_policy (struct secpolicy *src);
  200: static int ipsec_set_policy (struct secpolicy **pcb_sp,
  201: 	int optname, caddr_t request, size_t len, int priv);
  202: static int ipsec_get_policy (struct secpolicy *pcb_sp, struct mbuf **mp);
  203: static void vshiftl (unsigned char *, int, int);
  204: static size_t ipsec_hdrsiz (struct secpolicy *);
  205: 
  206: /*
  207:  * Return a held reference to the default SP.
  208:  */
  209: static struct secpolicy *
  210: key_allocsp_default(const char* where, int tag)
  211: {
  212: 	struct secpolicy *sp;
  213: 
  214: 	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  215: 		printf("DP key_allocsp_default from %s:%u\n", where, tag));
  216: 
  217: 	sp = &ip4_def_policy;
  218: 	if (sp->policy != IPSEC_POLICY_DISCARD &&
  219: 	    sp->policy != IPSEC_POLICY_NONE) {
  220: 		ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
  221: 		    sp->policy, IPSEC_POLICY_NONE));
  222: 		sp->policy = IPSEC_POLICY_NONE;
  223: 	}
  224: 	sp->refcnt++;
  225: 
  226: 	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  227: 		printf("DP key_allocsp_default returns SP:%p (%u)\n",
  228: 			sp, sp->refcnt));
  229: 	return sp;
  230: }
  231: #define	KEY_ALLOCSP_DEFAULT() \
  232: 	key_allocsp_default(__FILE__, __LINE__)
  233: 
  234: /*
  235:  * For OUTBOUND packet having a socket. Searching SPD for packet,
  236:  * and return a pointer to SP.
  237:  * OUT:	NULL:	no apropreate SP found, the following value is set to error.
  238:  *		0	: bypass
  239:  *		EACCES	: discard packet.
  240:  *		ENOENT	: ipsec_acquire() in progress, maybe.
  241:  *		others	: error occured.
  242:  *	others:	a pointer to SP
  243:  *
  244:  * NOTE: IPv6 mapped adddress concern is implemented here.
  245:  */
  246: struct secpolicy *
  247: ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
  248: {
  249: 	struct secpolicy *sp;
  250: 
  251: 	KASSERT(tdbi != NULL, ("ipsec_getpolicy: null tdbi"));
  252: 	KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  253: 		("ipsec_getpolicy: invalid direction %u", dir));
  254: 
  255: 	sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
  256: 	if (sp == NULL)			/*XXX????*/
  257: 		sp = KEY_ALLOCSP_DEFAULT();
  258: 	KASSERT(sp != NULL, ("ipsec_getpolicy: null SP"));
  259: 	return sp;
  260: }
  261: 
  262: /*
  263:  * For OUTBOUND packet having a socket. Searching SPD for packet,
  264:  * and return a pointer to SP.
  265:  * OUT:	NULL:	no apropreate SP found, the following value is set to error.
  266:  *		0	: bypass
  267:  *		EACCES	: discard packet.
  268:  *		ENOENT	: ipsec_acquire() in progress, maybe.
  269:  *		others	: error occured.
  270:  *	others:	a pointer to SP
  271:  *
  272:  * NOTE: IPv6 mapped adddress concern is implemented here.
  273:  */
  274: struct secpolicy *
  275: ipsec_getpolicybysock(m, dir, inp, error)
  276: 	struct mbuf *m;
  277: 	u_int dir;
  278: 	struct inpcb *inp;
  279: 	int *error;
  280: {
  281: 	struct inpcbpolicy *pcbsp = NULL;
  282: 	struct secpolicy *currsp = NULL;	/* policy on socket */
  283: 	struct secpolicy *sp;
  284: 	int af;
  285: 
  286: 	KASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
  287: 	KASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
  288: 	KASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
  289: 	KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  290: 		("ipsec_getpolicybysock: invalid direction %u", dir));
  291: 
  292: 	af = inp->inp_socket->so_proto->pr_domain->dom_family;
  293: 	KASSERT(af == AF_INET || af == AF_INET6,
  294: 		("ipsec_getpolicybysock: unexpected protocol family %u", af));
  295: 
  296: 	switch (af) {
  297: 	case AF_INET:
  298: 		/* set spidx in pcb */
  299: 		*error = ipsec4_setspidx_inpcb(m, inp);
  300: 		pcbsp = inp->inp_sp;
  301: 		break;
  302: #ifdef INET6
  303: 	case AF_INET6:
  304: 		/* set spidx in pcb */
  305: 		*error = ipsec6_setspidx_in6pcb(m, inp);
  306: 		pcbsp = inp->in6p_sp;
  307: 		break;
  308: #endif
  309: 	default:
  310: 		*error = EPFNOSUPPORT;
  311: 		break;
  312: 	}
  313: 	if (*error)
  314: 		return NULL;
  315: 
  316: 	KASSERT(pcbsp != NULL, ("ipsec_getpolicybysock: null pcbsp"));
  317: 	switch (dir) {
  318: 	case IPSEC_DIR_INBOUND:
  319: 		currsp = pcbsp->sp_in;
  320: 		break;
  321: 	case IPSEC_DIR_OUTBOUND:
  322: 		currsp = pcbsp->sp_out;
  323: 		break;
  324: 	}
  325: 	KASSERT(currsp != NULL, ("ipsec_getpolicybysock: null currsp"));
  326: 
  327: 	if (pcbsp->priv) {			/* when privilieged socket */
  328: 		switch (currsp->policy) {
  329: 		case IPSEC_POLICY_BYPASS:
  330: 		case IPSEC_POLICY_IPSEC:
  331: 			currsp->refcnt++;
  332: 			sp = currsp;
  333: 			break;
  334: 
  335: 		case IPSEC_POLICY_ENTRUST:
  336: 			/* look for a policy in SPD */
  337: 			sp = KEY_ALLOCSP(&currsp->spidx, dir);
  338: 			if (sp == NULL)		/* no SP found */
  339: 				sp = KEY_ALLOCSP_DEFAULT();
  340: 			break;
  341: 
  342: 		default:
  343: 			ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
  344: 			      "Invalid policy for PCB %d\n", currsp->policy));
  345: 			*error = EINVAL;
  346: 			return NULL;
  347: 		}
  348: 	} else {				/* unpriv, SPD has policy */
  349: 		sp = KEY_ALLOCSP(&currsp->spidx, dir);
  350: 		if (sp == NULL) {		/* no SP found */
  351: 			switch (currsp->policy) {
  352: 			case IPSEC_POLICY_BYPASS:
  353: 				ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
  354: 				       "Illegal policy for non-priviliged defined %d\n",
  355: 					currsp->policy));
  356: 				*error = EINVAL;
  357: 				return NULL;
  358: 
  359: 			case IPSEC_POLICY_ENTRUST:
  360: 				sp = KEY_ALLOCSP_DEFAULT();
  361: 				break;
  362: 
  363: 			case IPSEC_POLICY_IPSEC:
  364: 				currsp->refcnt++;
  365: 				sp = currsp;
  366: 				break;
  367: 
  368: 			default:
  369: 				ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
  370: 				   "Invalid policy for PCB %d\n", currsp->policy));
  371: 				*error = EINVAL;
  372: 				return NULL;
  373: 			}
  374: 		}
  375: 	}
  376: 	KASSERT(sp != NULL,
  377: 		("ipsec_getpolicybysock: null SP (priv %u policy %u",
  378: 		 pcbsp->priv, currsp->policy));
  379: 	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
  380: 		printf("DP ipsec_getpolicybysock (priv %u policy %u) allocates "
  381: 		       "SP:%p (refcnt %u)\n", pcbsp->priv, currsp->policy,
  382: 		       sp, sp->refcnt));
  383: 	return sp;
  384: }
  385: 
  386: /*
  387:  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
  388:  * and return a pointer to SP.
  389:  * OUT:	positive: a pointer to the entry for security policy leaf matched.
  390:  *	NULL:	no apropreate SP found, the following value is set to error.
  391:  *		0	: bypass
  392:  *		EACCES	: discard packet.
  393:  *		ENOENT	: ipsec_acquire() in progress, maybe.
  394:  *		others	: error occured.
  395:  */
  396: struct secpolicy *
  397: ipsec_getpolicybyaddr(m, dir, flag, error)
  398: 	struct mbuf *m;
  399: 	u_int dir;
  400: 	int flag;
  401: 	int *error;
  402: {
  403: 	struct secpolicyindex spidx;
  404: 	struct secpolicy *sp;
  405: 
  406: 	KASSERT(m != NULL, ("ipsec_getpolicybyaddr: null mbuf"));
  407: 	KASSERT(error != NULL, ("ipsec_getpolicybyaddr: null error"));
  408: 	KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
  409: 		("ipsec4_getpolicybaddr: invalid direction %u", dir));
  410: 
  411: 	sp = NULL;
  412: 	if (key_havesp(dir)) {
  413: 		/* Make an index to look for a policy. */
  414: 		*error = ipsec_setspidx(m, &spidx,
  415: 					(flag & IP_FORWARDING) ? 0 : 1);
  416: 		if (*error != 0) {
  417: 			DPRINTF(("ipsec_getpolicybyaddr: setpidx failed,"
  418: 				" dir %u flag %u\n", dir, flag));
  419: 			bzero(&spidx, sizeof (spidx));
  420: 			return NULL;
  421: 		}
  422: 		spidx.dir = dir;
  423: 
  424: 		sp = KEY_ALLOCSP(&spidx, dir);
  425: 	}
  426: 	if (sp == NULL)			/* no SP found, use system default */
  427: 		sp = KEY_ALLOCSP_DEFAULT();
  428: 	KASSERT(sp != NULL, ("ipsec_getpolicybyaddr: null SP"));
  429: 	return sp;
  430: }
  431: 
  432: struct secpolicy *
  433: ipsec4_checkpolicy(m, dir, flag, error, inp)
  434: 	struct mbuf *m;
  435: 	u_int dir, flag;
  436: 	int *error;
  437: 	struct inpcb *inp;
  438: {
  439: 	struct secpolicy *sp;
  440: 
  441: 	*error = 0;
  442: 	if (inp == NULL)
  443: 		sp = ipsec_getpolicybyaddr(m, dir, flag, error);
  444: 	else
  445: 		sp = ipsec_getpolicybysock(m, dir, inp, error);
  446: 	if (sp == NULL) {
  447: 		KASSERT(*error != 0,
  448: 			("ipsec4_checkpolicy: getpolicy failed w/o error"));
  449: 		newipsecstat.ips_out_inval++;
  450: 		return NULL;
  451: 	}
  452: 	KASSERT(*error == 0,
  453: 		("ipsec4_checkpolicy: sp w/ error set to %u", *error));
  454: 	switch (sp->policy) {
  455: 	case IPSEC_POLICY_ENTRUST:
  456: 	default:
  457: 		printf("ipsec4_checkpolicy: invalid policy %u\n", sp->policy);
  458: 		/* fall thru... */
  459: 	case IPSEC_POLICY_DISCARD:
  460: 		newipsecstat.ips_out_polvio++;
  461: 		*error = -EINVAL;	/* packet is discarded by caller */
  462: 		break;
  463: 	case IPSEC_POLICY_BYPASS:
  464: 	case IPSEC_POLICY_NONE:
  465: 		KEY_FREESP(&sp);
  466: 		sp = NULL;		/* NB: force NULL result */
  467: 		break;
  468: 	case IPSEC_POLICY_IPSEC:
  469: 		if (sp->req == NULL)	/* acquire an SA */
  470: 			*error = key_spdacquire(sp);
  471: 		break;
  472: 	}
  473: 	if (*error != 0) {
  474: 		KEY_FREESP(&sp);
  475: 		sp = NULL;
  476: 	}
  477: 	return sp;
  478: }
  479: 
  480: static int
  481: ipsec4_setspidx_inpcb(m, pcb)
  482: 	struct mbuf *m;
  483: 	struct inpcb *pcb;
  484: {
  485: 	int error;
  486: 
  487: 	KASSERT(pcb != NULL, ("ipsec4_setspidx_inpcb: null pcb"));
  488: 	KASSERT(pcb->inp_sp != NULL, ("ipsec4_setspidx_inpcb: null inp_sp"));
  489: 	KASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
  490: 		("ipsec4_setspidx_inpcb: null sp_in || sp_out"));
  491: 
  492: 	error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
  493: 	if (error == 0) {
  494: 		pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
  495: 		pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
  496: 		pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
  497: 	} else {
  498: 		bzero(&pcb->inp_sp->sp_in->spidx,
  499: 			sizeof (pcb->inp_sp->sp_in->spidx));
  500: 		bzero(&pcb->inp_sp->sp_out->spidx,
  501: 			sizeof (pcb->inp_sp->sp_in->spidx));
  502: 	}
  503: 	return error;
  504: }
  505: 
  506: #ifdef INET6
  507: static int
  508: ipsec6_setspidx_in6pcb(m, pcb)
  509: 	struct mbuf *m;
  510: 	struct in6pcb *pcb;
  511: {
  512: 	struct secpolicyindex *spidx;
  513: 	int error;
  514: 
  515: 	KASSERT(pcb != NULL, ("ipsec6_setspidx_in6pcb: null pcb"));
  516: 	KASSERT(pcb->in6p_sp != NULL, ("ipsec6_setspidx_in6pcb: null inp_sp"));
  517: 	KASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
  518: 		("ipsec6_setspidx_in6pcb: null sp_in || sp_out"));
  519: 
  520: 	bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
  521: 	bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
  522: 
  523: 	spidx = &pcb->in6p_sp->sp_in->spidx;
  524: 	error = ipsec_setspidx(m, spidx, 1);
  525: 	if (error)
  526: 		goto bad;
  527: 	spidx->dir = IPSEC_DIR_INBOUND;
  528: 
  529: 	spidx = &pcb->in6p_sp->sp_out->spidx;
  530: 	error = ipsec_setspidx(m, spidx, 1);
  531: 	if (error)
  532: 		goto bad;
  533: 	spidx->dir = IPSEC_DIR_OUTBOUND;
  534: 
  535: 	return 0;
  536: 
  537: bad:
  538: 	bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
  539: 	bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
  540: 	return error;
  541: }
  542: #endif
  543: 
  544: /*
  545:  * configure security policy index (src/dst/proto/sport/dport)
  546:  * by looking at the content of mbuf.
  547:  * the caller is responsible for error recovery (like clearing up spidx).
  548:  */
  549: static int
  550: ipsec_setspidx(m, spidx, needport)
  551: 	struct mbuf *m;
  552: 	struct secpolicyindex *spidx;
  553: 	int needport;
  554: {
  555: 	struct ip *ip = NULL;
  556: 	struct ip ipbuf;
  557: 	u_int v;
  558: 	struct mbuf *n;
  559: 	int len;
  560: 	int error;
  561: 
  562: 	KASSERT(m != NULL, ("ipsec_setspidx: null mbuf"));
  563: 
  564: 	/*
  565: 	 * validate m->m_pkthdr.len.  we see incorrect length if we
  566: 	 * mistakenly call this function with inconsistent mbuf chain
  567: 	 * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
  568: 	 */
  569: 	len = 0;
  570: 	for (n = m; n; n = n->m_next)
  571: 		len += n->m_len;
  572: 	if (m->m_pkthdr.len != len) {
  573: 		KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  574: 			printf("ipsec_setspidx: "
  575: 			       "total of m_len(%d) != pkthdr.len(%d), "
  576: 			       "ignored.\n",
  577: 				len, m->m_pkthdr.len));
  578: 		return EINVAL;
  579: 	}
  580: 
  581: 	if (m->m_pkthdr.len < sizeof(struct ip)) {
  582: 		KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  583: 			printf("ipsec_setspidx: "
  584: 			    "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
  585: 			    m->m_pkthdr.len));
  586: 		return EINVAL;
  587: 	}
  588: 
  589: 	if (m->m_len >= sizeof(*ip))
  590: 		ip = mtod(m, struct ip *);
  591: 	else {
  592: 		m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
  593: 		ip = &ipbuf;
  594: 	}
  595: #ifdef _IP_VHL
  596: 	v = _IP_VHL_V(ip->ip_vhl);
  597: #else
  598: 	v = ip->ip_v;
  599: #endif
  600: 	switch (v) {
  601: 	case 4:
  602: 		error = ipsec4_setspidx_ipaddr(m, spidx);
  603: 		if (error)
  604: 			return error;
  605: 		ipsec4_get_ulp(m, spidx, needport);
  606: 		return 0;
  607: #ifdef INET6
  608: 	case 6:
  609: 		if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
  610: 			KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  611: 				printf("ipsec_setspidx: "
  612: 				    "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
  613: 				    "ignored.\n", m->m_pkthdr.len));
  614: 			return EINVAL;
  615: 		}
  616: 		error = ipsec6_setspidx_ipaddr(m, spidx);
  617: 		if (error)
  618: 			return error;
  619: 		ipsec6_get_ulp(m, spidx, needport);
  620: 		return 0;
  621: #endif
  622: 	default:
  623: 		KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  624: 			printf("ipsec_setspidx: "
  625: 			    "unknown IP version %u, ignored.\n", v));
  626: 		return EINVAL;
  627: 	}
  628: }
  629: 
  630: static void
  631: ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
  632: {
  633: 	u_int8_t nxt;
  634: 	int off;
  635: 
  636: 	/* sanity check */
  637: 	KASSERT(m != NULL, ("ipsec4_get_ulp: null mbuf"));
  638: 	KASSERT(m->m_pkthdr.len >= sizeof(struct ip),
  639: 		("ipsec4_get_ulp: packet too short"));
  640: 
  641: 	/* NB: ip_input() flips it into host endian XXX need more checking */
  642: 	if (m->m_len < sizeof (struct ip)) {
  643: 		struct ip *ip = mtod(m, struct ip *);
  644: 		if (ip->ip_off & (IP_MF | IP_OFFMASK))
  645: 			goto done;
  646: #ifdef _IP_VHL
  647: 		off = _IP_VHL_HL(ip->ip_vhl) << 2;
  648: #else
  649: 		off = ip->ip_hl << 2;
  650: #endif
  651: 		nxt = ip->ip_p;
  652: 	} else {
  653: 		struct ip ih;
  654: 
  655: 		m_copydata(m, 0, sizeof (struct ip), (caddr_t) &ih);
  656: 		if (ih.ip_off & (IP_MF | IP_OFFMASK))
  657: 			goto done;
  658: #ifdef _IP_VHL
  659: 		off = _IP_VHL_HL(ih.ip_vhl) << 2;
  660: #else
  661: 		off = ih.ip_hl << 2;
  662: #endif
  663: 		nxt = ih.ip_p;
  664: 	}
  665: 
  666: 	while (off < m->m_pkthdr.len) {
  667: 		struct ip6_ext ip6e;
  668: 		struct tcphdr th;
  669: 		struct udphdr uh;
  670: 
  671: 		switch (nxt) {
  672: 		case IPPROTO_TCP:
  673: 			spidx->ul_proto = nxt;
  674: 			if (!needport)
  675: 				goto done_proto;
  676: 			if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
  677: 				goto done;
  678: 			m_copydata(m, off, sizeof (th), (caddr_t) &th);
  679: 			spidx->src.sin.sin_port = th.th_sport;
  680: 			spidx->dst.sin.sin_port = th.th_dport;
  681: 			return;
  682: 		case IPPROTO_UDP:
  683: 			spidx->ul_proto = nxt;
  684: 			if (!needport)
  685: 				goto done_proto;
  686: 			if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
  687: 				goto done;
  688: 			m_copydata(m, off, sizeof (uh), (caddr_t) &uh);
  689: 			spidx->src.sin.sin_port = uh.uh_sport;
  690: 			spidx->dst.sin.sin_port = uh.uh_dport;
  691: 			return;
  692: 		case IPPROTO_AH:
  693: 			if (m->m_pkthdr.len > off + sizeof(ip6e))
  694: 				goto done;
  695: 			/* XXX sigh, this works but is totally bogus */
  696: 			m_copydata(m, off, sizeof(ip6e), (caddr_t) &ip6e);
  697: 			off += (ip6e.ip6e_len + 2) << 2;
  698: 			nxt = ip6e.ip6e_nxt;
  699: 			break;
  700: 		case IPPROTO_ICMP:
  701: 		default:
  702: 			/* XXX intermediate headers??? */
  703: 			spidx->ul_proto = nxt;
  704: 			goto done_proto;
  705: 		}
  706: 	}
  707: done:
  708: 	spidx->ul_proto = IPSEC_ULPROTO_ANY;
  709: done_proto:
  710: 	spidx->src.sin.sin_port = IPSEC_PORT_ANY;
  711: 	spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
  712: }
  713: 
  714: /* assumes that m is sane */
  715: static int
  716: ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
  717: {
  718: 	static const struct sockaddr_in template = {
  719: 		sizeof (struct sockaddr_in),
  720: 		AF_INET,
  721: 		0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
  722: 	};
  723: 
  724: 	spidx->src.sin = template;
  725: 	spidx->dst.sin = template;
  726: 
  727: 	if (m->m_len < sizeof (struct ip)) {
  728: 		m_copydata(m, offsetof(struct ip, ip_src),
  729: 			   sizeof (struct  in_addr),
  730: 			   (caddr_t) &spidx->src.sin.sin_addr);
  731: 		m_copydata(m, offsetof(struct ip, ip_dst),
  732: 			   sizeof (struct  in_addr),
  733: 			   (caddr_t) &spidx->dst.sin.sin_addr);
  734: 	} else {
  735: 		struct ip *ip = mtod(m, struct ip *);
  736: 		spidx->src.sin.sin_addr = ip->ip_src;
  737: 		spidx->dst.sin.sin_addr = ip->ip_dst;
  738: 	}
  739: 
  740: 	spidx->prefs = sizeof(struct in_addr) << 3;
  741: 	spidx->prefd = sizeof(struct in_addr) << 3;
  742: 
  743: 	return 0;
  744: }
  745: 
  746: #ifdef INET6
  747: static void
  748: ipsec6_get_ulp(m, spidx, needport)
  749: 	struct mbuf *m;
  750: 	struct secpolicyindex *spidx;
  751: 	int needport;
  752: {
  753: 	int off, nxt;
  754: 	struct tcphdr th;
  755: 	struct udphdr uh;
  756: 
  757: 	/* sanity check */
  758: 	if (m == NULL)
  759: 		panic("ipsec6_get_ulp: NULL pointer was passed.\n");
  760: 
  761: 	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
  762: 		printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
  763: 
  764: 	/* set default */
  765: 	spidx->ul_proto = IPSEC_ULPROTO_ANY;
  766: 	((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
  767: 	((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
  768: 
  769: 	nxt = -1;
  770: 	off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
  771: 	if (off < 0 || m->m_pkthdr.len < off)
  772: 		return;
  773: 
  774: 	switch (nxt) {
  775: 	case IPPROTO_TCP:
  776: 		spidx->ul_proto = nxt;
  777: 		if (!needport)
  778: 			break;
  779: 		if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
  780: 			break;
  781: 		m_copydata(m, off, sizeof(th), (caddr_t)&th);
  782: 		((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
  783: 		((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
  784: 		break;
  785: 	case IPPROTO_UDP:
  786: 		spidx->ul_proto = nxt;
  787: 		if (!needport)
  788: 			break;
  789: 		if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
  790: 			break;
  791: 		m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
  792: 		((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
  793: 		((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
  794: 		break;
  795: 	case IPPROTO_ICMPV6:
  796: 	default:
  797: 		/* XXX intermediate headers??? */
  798: 		spidx->ul_proto = nxt;
  799: 		break;
  800: 	}
  801: }
  802: 
  803: /* assumes that m is sane */
  804: static int
  805: ipsec6_setspidx_ipaddr(m, spidx)
  806: 	struct mbuf *m;
  807: 	struct secpolicyindex *spidx;
  808: {
  809: 	struct ip6_hdr *ip6 = NULL;
  810: 	struct ip6_hdr ip6buf;
  811: 	struct sockaddr_in6 *sin6;
  812: 
  813: 	if (m->m_len >= sizeof(*ip6))
  814: 		ip6 = mtod(m, struct ip6_hdr *);
  815: 	else {
  816: 		m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
  817: 		ip6 = &ip6buf;
  818: 	}
  819: 
  820: 	sin6 = (struct sockaddr_in6 *)&spidx->src;
  821: 	bzero(sin6, sizeof(*sin6));
  822: 	sin6->sin6_family = AF_INET6;
  823: 	sin6->sin6_len = sizeof(struct sockaddr_in6);
  824: 	bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
  825: 	if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
  826: 		sin6->sin6_addr.s6_addr16[1] = 0;
  827: 		sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
  828: 	}
  829: 	spidx->prefs = sizeof(struct in6_addr) << 3;
  830: 
  831: 	sin6 = (struct sockaddr_in6 *)&spidx->dst;
  832: 	bzero(sin6, sizeof(*sin6));
  833: 	sin6->sin6_family = AF_INET6;
  834: 	sin6->sin6_len = sizeof(struct sockaddr_in6);
  835: 	bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
  836: 	if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
  837: 		sin6->sin6_addr.s6_addr16[1] = 0;
  838: 		sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
  839: 	}
  840: 	spidx->prefd = sizeof(struct in6_addr) << 3;
  841: 
  842: 	return 0;
  843: }
  844: #endif
  845: 
  846: static void
  847: ipsec_delpcbpolicy(p)
  848: 	struct inpcbpolicy *p;
  849: {
  850: 	free(p, M_SECA);
  851: }
  852: 
  853: /* initialize policy in PCB */
  854: int
  855: ipsec_init_policy(so, pcb_sp)
  856: 	struct socket *so;
  857: 	struct inpcbpolicy **pcb_sp;
  858: {
  859: 	struct inpcbpolicy *new;
  860: 
  861: 	/* sanity check. */
  862: 	if (so == NULL || pcb_sp == NULL)
  863: 		panic("ipsec_init_policy: NULL pointer was passed.\n");
  864: 
  865: 	new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
  866: 					    M_SECA, M_NOWAIT|M_ZERO);
  867: 	if (new == NULL) {
  868: 		ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
  869: 		return ENOBUFS;
  870: 	}
  871: 
  872: 	if (so->so_cred != 0 && so->so_cred->cr_uid == 0)
  873: 		new->priv = 1;
  874: 	else
  875: 		new->priv = 0;
  876: 
  877: 	if ((new->sp_in = KEY_NEWSP()) == NULL) {
  878: 		ipsec_delpcbpolicy(new);
  879: 		return ENOBUFS;
  880: 	}
  881: 	new->sp_in->state = IPSEC_SPSTATE_ALIVE;
  882: 	new->sp_in->policy = IPSEC_POLICY_ENTRUST;
  883: 
  884: 	if ((new->sp_out = KEY_NEWSP()) == NULL) {
  885: 		KEY_FREESP(&new->sp_in);
  886: 		ipsec_delpcbpolicy(new);
  887: 		return ENOBUFS;
  888: 	}
  889: 	new->sp_out->state = IPSEC_SPSTATE_ALIVE;
  890: 	new->sp_out->policy = IPSEC_POLICY_ENTRUST;
  891: 
  892: 	*pcb_sp = new;
  893: 
  894: 	return 0;
  895: }
  896: 
  897: /* copy old ipsec policy into new */
  898: int
  899: ipsec_copy_policy(old, new)
  900: 	struct inpcbpolicy *old, *new;
  901: {
  902: 	struct secpolicy *sp;
  903: 
  904: 	sp = ipsec_deepcopy_policy(old->sp_in);
  905: 	if (sp) {
  906: 		KEY_FREESP(&new->sp_in);
  907: 		new->sp_in = sp;
  908: 	} else
  909: 		return ENOBUFS;
  910: 
  911: 	sp = ipsec_deepcopy_policy(old->sp_out);
  912: 	if (sp) {
  913: 		KEY_FREESP(&new->sp_out);
  914: 		new->sp_out = sp;
  915: 	} else
  916: 		return ENOBUFS;
  917: 
  918: 	new->priv = old->priv;
  919: 
  920: 	return 0;
  921: }
  922: 
  923: /* deep-copy a policy in PCB */
  924: static struct secpolicy *
  925: ipsec_deepcopy_policy(src)
  926: 	struct secpolicy *src;
  927: {
  928: 	struct ipsecrequest *newchain = NULL;
  929: 	struct ipsecrequest *p;
  930: 	struct ipsecrequest **q;
  931: 	struct ipsecrequest *r;
  932: 	struct secpolicy *dst;
  933: 
  934: 	if (src == NULL)
  935: 		return NULL;
  936: 	dst = KEY_NEWSP();
  937: 	if (dst == NULL)
  938: 		return NULL;
  939: 
  940: 	/*
  941: 	 * deep-copy IPsec request chain.  This is required since struct
  942: 	 * ipsecrequest is not reference counted.
  943: 	 */
  944: 	q = &newchain;
  945: 	for (p = src->req; p; p = p->next) {
  946: 		*q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
  947: 			M_SECA, M_NOWAIT);
  948: 		if (*q == NULL)
  949: 			goto fail;
  950: 		bzero(*q, sizeof(**q));
  951: 		(*q)->next = NULL;
  952: 
  953: 		(*q)->saidx.proto = p->saidx.proto;
  954: 		(*q)->saidx.mode = p->saidx.mode;
  955: 		(*q)->level = p->level;
  956: 		(*q)->saidx.reqid = p->saidx.reqid;
  957: 
  958: 		bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
  959: 		bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
  960: 
  961: 		(*q)->sav = NULL;
  962: 		(*q)->sp = dst;
  963: 
  964: 		q = &((*q)->next);
  965: 	}
  966: 
  967: 	dst->req = newchain;
  968: 	dst->state = src->state;
  969: 	dst->policy = src->policy;
  970: 	/* do not touch the refcnt fields */
  971: 
  972: 	return dst;
  973: 
  974: fail:
  975: 	for (p = newchain; p; p = r) {
  976: 		r = p->next;
  977: 		free(p, M_SECA);
  978: 		p = NULL;
  979: 	}
  980: 	return NULL;
  981: }
  982: 
  983: /* set policy and ipsec request if present. */
  984: static int
  985: ipsec_set_policy(pcb_sp, optname, request, len, priv)
  986: 	struct secpolicy **pcb_sp;
  987: 	int optname;
  988: 	caddr_t request;
  989: 	size_t len;
  990: 	int priv;
  991: {
  992: 	struct sadb_x_policy *xpl;
  993: 	struct secpolicy *newsp = NULL;
  994: 	int error;
  995: 
  996: 	/* sanity check. */
  997: 	if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
  998: 		return EINVAL;
  999: 	if (len < sizeof(*xpl))
 1000: 		return EINVAL;
 1001: 	xpl = (struct sadb_x_policy *)request;
 1002: 
 1003: 	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1004: 		printf("ipsec_set_policy: passed policy\n");
 1005: 		kdebug_sadb_x_policy((struct sadb_ext *)xpl));
 1006: 
 1007: 	/* check policy type */
 1008: 	/* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
 1009: 	if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
 1010: 	 || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
 1011: 		return EINVAL;
 1012: 
 1013: 	/* check privileged socket */
 1014: 	if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
 1015: 		return EACCES;
 1016: 
 1017: 	/* allocation new SP entry */
 1018: 	if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
 1019: 		return error;
 1020: 
 1021: 	newsp->state = IPSEC_SPSTATE_ALIVE;
 1022: 
 1023: 	/* clear old SP and set new SP */
 1024: 	KEY_FREESP(pcb_sp);
 1025: 	*pcb_sp = newsp;
 1026: 	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1027: 		printf("ipsec_set_policy: new policy\n");
 1028: 		kdebug_secpolicy(newsp));
 1029: 
 1030: 	return 0;
 1031: }
 1032: 
 1033: static int
 1034: ipsec_get_policy(pcb_sp, mp)
 1035: 	struct secpolicy *pcb_sp;
 1036: 	struct mbuf **mp;
 1037: {
 1038: 
 1039: 	/* sanity check. */
 1040: 	if (pcb_sp == NULL || mp == NULL)
 1041: 		return EINVAL;
 1042: 
 1043: 	*mp = key_sp2msg(pcb_sp);
 1044: 	if (!*mp) {
 1045: 		ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
 1046: 		return ENOBUFS;
 1047: 	}
 1048: 
 1049: 	(*mp)->m_type = MT_DATA;
 1050: 	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1051: 		printf("ipsec_get_policy:\n");
 1052: 		kdebug_mbuf(*mp));
 1053: 
 1054: 	return 0;
 1055: }
 1056: 
 1057: int
 1058: ipsec4_set_policy(inp, optname, request, len, priv)
 1059: 	struct inpcb *inp;
 1060: 	int optname;
 1061: 	caddr_t request;
 1062: 	size_t len;
 1063: 	int priv;
 1064: {
 1065: 	struct sadb_x_policy *xpl;
 1066: 	struct secpolicy **pcb_sp;
 1067: 
 1068: 	/* sanity check. */
 1069: 	if (inp == NULL || request == NULL)
 1070: 		return EINVAL;
 1071: 	if (len < sizeof(*xpl))
 1072: 		return EINVAL;
 1073: 	xpl = (struct sadb_x_policy *)request;
 1074: 
 1075: 	/* select direction */
 1076: 	switch (xpl->sadb_x_policy_dir) {
 1077: 	case IPSEC_DIR_INBOUND:
 1078: 		pcb_sp = &inp->inp_sp->sp_in;
 1079: 		break;
 1080: 	case IPSEC_DIR_OUTBOUND:
 1081: 		pcb_sp = &inp->inp_sp->sp_out;
 1082: 		break;
 1083: 	default:
 1084: 		ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
 1085: 			xpl->sadb_x_policy_dir));
 1086: 		return EINVAL;
 1087: 	}
 1088: 
 1089: 	return ipsec_set_policy(pcb_sp, optname, request, len, priv);
 1090: }
 1091: 
 1092: int
 1093: ipsec4_get_policy(inp, request, len, mp)
 1094: 	struct inpcb *inp;
 1095: 	caddr_t request;
 1096: 	size_t len;
 1097: 	struct mbuf **mp;
 1098: {
 1099: 	struct sadb_x_policy *xpl;
 1100: 	struct secpolicy *pcb_sp;
 1101: 
 1102: 	/* sanity check. */
 1103: 	if (inp == NULL || request == NULL || mp == NULL)
 1104: 		return EINVAL;
 1105: 	KASSERT(inp->inp_sp != NULL, ("ipsec4_get_policy: null inp_sp"));
 1106: 	if (len < sizeof(*xpl))
 1107: 		return EINVAL;
 1108: 	xpl = (struct sadb_x_policy *)request;
 1109: 
 1110: 	/* select direction */
 1111: 	switch (xpl->sadb_x_policy_dir) {
 1112: 	case IPSEC_DIR_INBOUND:
 1113: 		pcb_sp = inp->inp_sp->sp_in;
 1114: 		break;
 1115: 	case IPSEC_DIR_OUTBOUND:
 1116: 		pcb_sp = inp->inp_sp->sp_out;
 1117: 		break;
 1118: 	default:
 1119: 		ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
 1120: 			xpl->sadb_x_policy_dir));
 1121: 		return EINVAL;
 1122: 	}
 1123: 
 1124: 	return ipsec_get_policy(pcb_sp, mp);
 1125: }
 1126: 
 1127: /* delete policy in PCB */
 1128: int
 1129: ipsec4_delete_pcbpolicy(inp)
 1130: 	struct inpcb *inp;
 1131: {
 1132: 	KASSERT(inp != NULL, ("ipsec4_delete_pcbpolicy: null inp"));
 1133: 
 1134: 	if (inp->inp_sp == NULL)
 1135: 		return 0;
 1136: 
 1137: 	if (inp->inp_sp->sp_in != NULL)
 1138: 		KEY_FREESP(&inp->inp_sp->sp_in);
 1139: 
 1140: 	if (inp->inp_sp->sp_out != NULL)
 1141: 		KEY_FREESP(&inp->inp_sp->sp_out);
 1142: 
 1143: 	ipsec_delpcbpolicy(inp->inp_sp);
 1144: 	inp->inp_sp = NULL;
 1145: 
 1146: 	return 0;
 1147: }
 1148: 
 1149: #ifdef INET6
 1150: int
 1151: ipsec6_set_policy(in6p, optname, request, len, priv)
 1152: 	struct in6pcb *in6p;
 1153: 	int optname;
 1154: 	caddr_t request;
 1155: 	size_t len;
 1156: 	int priv;
 1157: {
 1158: 	struct sadb_x_policy *xpl;
 1159: 	struct secpolicy **pcb_sp;
 1160: 
 1161: 	/* sanity check. */
 1162: 	if (in6p == NULL || request == NULL)
 1163: 		return EINVAL;
 1164: 	if (len < sizeof(*xpl))
 1165: 		return EINVAL;
 1166: 	xpl = (struct sadb_x_policy *)request;
 1167: 
 1168: 	/* select direction */
 1169: 	switch (xpl->sadb_x_policy_dir) {
 1170: 	case IPSEC_DIR_INBOUND:
 1171: 		pcb_sp = &in6p->in6p_sp->sp_in;
 1172: 		break;
 1173: 	case IPSEC_DIR_OUTBOUND:
 1174: 		pcb_sp = &in6p->in6p_sp->sp_out;
 1175: 		break;
 1176: 	default:
 1177: 		ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
 1178: 			xpl->sadb_x_policy_dir));
 1179: 		return EINVAL;
 1180: 	}
 1181: 
 1182: 	return ipsec_set_policy(pcb_sp, optname, request, len, priv);
 1183: }
 1184: 
 1185: int
 1186: ipsec6_get_policy(in6p, request, len, mp)
 1187: 	struct in6pcb *in6p;
 1188: 	caddr_t request;
 1189: 	size_t len;
 1190: 	struct mbuf **mp;
 1191: {
 1192: 	struct sadb_x_policy *xpl;
 1193: 	struct secpolicy *pcb_sp;
 1194: 
 1195: 	/* sanity check. */
 1196: 	if (in6p == NULL || request == NULL || mp == NULL)
 1197: 		return EINVAL;
 1198: 	KASSERT(in6p->in6p_sp != NULL, ("ipsec6_get_policy: null in6p_sp"));
 1199: 	if (len < sizeof(*xpl))
 1200: 		return EINVAL;
 1201: 	xpl = (struct sadb_x_policy *)request;
 1202: 
 1203: 	/* select direction */
 1204: 	switch (xpl->sadb_x_policy_dir) {
 1205: 	case IPSEC_DIR_INBOUND:
 1206: 		pcb_sp = in6p->in6p_sp->sp_in;
 1207: 		break;
 1208: 	case IPSEC_DIR_OUTBOUND:
 1209: 		pcb_sp = in6p->in6p_sp->sp_out;
 1210: 		break;
 1211: 	default:
 1212: 		ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
 1213: 			xpl->sadb_x_policy_dir));
 1214: 		return EINVAL;
 1215: 	}
 1216: 
 1217: 	return ipsec_get_policy(pcb_sp, mp);
 1218: }
 1219: 
 1220: int
 1221: ipsec6_delete_pcbpolicy(in6p)
 1222: 	struct in6pcb *in6p;
 1223: {
 1224: 	KASSERT(in6p != NULL, ("ipsec6_delete_pcbpolicy: null in6p"));
 1225: 
 1226: 	if (in6p->in6p_sp == NULL)
 1227: 		return 0;
 1228: 
 1229: 	if (in6p->in6p_sp->sp_in != NULL)
 1230: 		KEY_FREESP(&in6p->in6p_sp->sp_in);
 1231: 
 1232: 	if (in6p->in6p_sp->sp_out != NULL)
 1233: 		KEY_FREESP(&in6p->in6p_sp->sp_out);
 1234: 
 1235: 	ipsec_delpcbpolicy(in6p->in6p_sp);
 1236: 	in6p->in6p_sp = NULL;
 1237: 
 1238: 	return 0;
 1239: }
 1240: #endif
 1241: 
 1242: /*
 1243:  * return current level.
 1244:  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
 1245:  */
 1246: u_int
 1247: ipsec_get_reqlevel(isr)
 1248: 	struct ipsecrequest *isr;
 1249: {
 1250: 	u_int level = 0;
 1251: 	u_int esp_trans_deflev, esp_net_deflev;
 1252: 	u_int ah_trans_deflev, ah_net_deflev;
 1253: 
 1254: 	KASSERT(isr != NULL && isr->sp != NULL,
 1255: 		("ipsec_get_reqlevel: null argument"));
 1256: 	KASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
 1257: 		("ipsec_get_reqlevel: af family mismatch, src %u, dst %u",
 1258: 		 isr->sp->spidx.src.sa.sa_family,
 1259: 		 isr->sp->spidx.dst.sa.sa_family));
 1260: 
 1261: /* XXX note that we have ipseclog() expanded here - code sync issue */
 1262: #define IPSEC_CHECK_DEFAULT(lev) \
 1263: 	(((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE	      \
 1264: 			&& (lev) != IPSEC_LEVEL_UNIQUE)			      \
 1265: 		? (ipsec_debug						      \
 1266: 			? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
 1267: 				(lev), IPSEC_LEVEL_REQUIRE)		      \
 1268: 			: 0),						      \
 1269: 			(lev) = IPSEC_LEVEL_REQUIRE,			      \
 1270: 			(lev)						      \
 1271: 		: (lev))
 1272: 
 1273: 	/* set default level */
 1274: 	switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
 1275: #ifdef INET
 1276: 	case AF_INET:
 1277: 		esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
 1278: 		esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
 1279: 		ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
 1280: 		ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
 1281: 		break;
 1282: #endif
 1283: #ifdef INET6
 1284: 	case AF_INET6:
 1285: 		esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
 1286: 		esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
 1287: 		ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
 1288: 		ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
 1289: 		break;
 1290: #endif /* INET6 */
 1291: 	default:
 1292: 		panic("key_get_reqlevel: unknown af %u",
 1293: 			isr->sp->spidx.src.sa.sa_family);
 1294: 	}
 1295: 
 1296: #undef IPSEC_CHECK_DEFAULT
 1297: 
 1298: 	/* set level */
 1299: 	switch (isr->level) {
 1300: 	case IPSEC_LEVEL_DEFAULT:
 1301: 		switch (isr->saidx.proto) {
 1302: 		case IPPROTO_ESP:
 1303: 			if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1304: 				level = esp_net_deflev;
 1305: 			else
 1306: 				level = esp_trans_deflev;
 1307: 			break;
 1308: 		case IPPROTO_AH:
 1309: 			if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 1310: 				level = ah_net_deflev;
 1311: 			else
 1312: 				level = ah_trans_deflev;
 1313: 		case IPPROTO_IPCOMP:
 1314: 			/*
 1315: 			 * we don't really care, as IPcomp document says that
 1316: 			 * we shouldn't compress small packets
 1317: 			 */
 1318: 			level = IPSEC_LEVEL_USE;
 1319: 			break;
 1320: 		default:
 1321: 			panic("ipsec_get_reqlevel: "
 1322: 				"Illegal protocol defined %u\n",
 1323: 				isr->saidx.proto);
 1324: 		}
 1325: 		break;
 1326: 
 1327: 	case IPSEC_LEVEL_USE:
 1328: 	case IPSEC_LEVEL_REQUIRE:
 1329: 		level = isr->level;
 1330: 		break;
 1331: 	case IPSEC_LEVEL_UNIQUE:
 1332: 		level = IPSEC_LEVEL_REQUIRE;
 1333: 		break;
 1334: 
 1335: 	default:
 1336: 		panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
 1337: 			isr->level);
 1338: 	}
 1339: 
 1340: 	return level;
 1341: }
 1342: 
 1343: /*
 1344:  * Check security policy requirements against the actual
 1345:  * packet contents.  Return one if the packet should be
 1346:  * reject as "invalid"; otherwiser return zero to have the
 1347:  * packet treated as "valid".
 1348:  *
 1349:  * OUT:
 1350:  *	0: valid
 1351:  *	1: invalid
 1352:  */
 1353: int
 1354: ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
 1355: {
 1356: 	struct ipsecrequest *isr;
 1357: 	int need_auth;
 1358: 
 1359: 	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1360: 		printf("ipsec_in_reject: using SP\n");
 1361: 		kdebug_secpolicy(sp));
 1362: 
 1363: 	/* check policy */
 1364: 	switch (sp->policy) {
 1365: 	case IPSEC_POLICY_DISCARD:
 1366: 		return 1;
 1367: 	case IPSEC_POLICY_BYPASS:
 1368: 	case IPSEC_POLICY_NONE:
 1369: 		return 0;
 1370: 	}
 1371: 
 1372: 	KASSERT(sp->policy == IPSEC_POLICY_IPSEC,
 1373: 		("ipsec_in_reject: invalid policy %u", sp->policy));
 1374: 
 1375: 	/* XXX should compare policy against ipsec header history */
 1376: 
 1377: 	need_auth = 0;
 1378: 	for (isr = sp->req; isr != NULL; isr = isr->next) {
 1379: 		if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
 1380: 			continue;
 1381: 		switch (isr->saidx.proto) {
 1382: 		case IPPROTO_ESP:
 1383: 			if ((m->m_flags & M_DECRYPTED) == 0) {
 1384: 				KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1385: 				    printf("ipsec_in_reject: ESP m_flags:%x\n",
 1386: 					    m->m_flags));
 1387: 				return 1;
 1388: 			}
 1389: 
 1390: 			if (!need_auth &&
 1391: 			    isr->sav != NULL &&
 1392: 			    isr->sav->tdb_authalgxform != NULL &&
 1393: 			    (m->m_flags & M_AUTHIPDGM) == 0) {
 1394: 				KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1395: 				    printf("ipsec_in_reject: ESP/AH m_flags:%x\n",
 1396: 					    m->m_flags));
 1397: 				return 1;
 1398: 			}
 1399: 			break;
 1400: 		case IPPROTO_AH:
 1401: 			need_auth = 1;
 1402: 			if ((m->m_flags & M_AUTHIPHDR) == 0) {
 1403: 				KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
 1404: 				    printf("ipsec_in_reject: AH m_flags:%x\n",
 1405: 					    m->m_flags));
 1406: 				return 1;
 1407: 			}
 1408: 			break;
 1409: 		case IPPROTO_IPCOMP:
 1410: 			/*
 1411: 			 * we don't really care, as IPcomp document
 1412: 			 * says that we shouldn't compress small
 1413: 			 * packets, IPComp policy should always be
 1414: 			 * treated as being in "use" level.
 1415: 			 */
 1416: 			break;
 1417: 		}
 1418: 	}
 1419: 	return 0;		/* valid */
 1420: }
 1421: 
 1422: /*
 1423:  * Check AH/ESP integrity.
 1424:  * This function is called from tcp_input(), udp_input(),
 1425:  * and {ah,esp}4_input for tunnel mode
 1426:  */
 1427: int
 1428: ipsec4_in_reject(m, inp)
 1429: 	struct mbuf *m;
 1430: 	struct inpcb *inp;
 1431: {
 1432: 	struct secpolicy *sp;
 1433: 	int error;
 1434: 	int result;
 1435: 
 1436: 	KASSERT(m != NULL, ("ipsec4_in_reject_so: null mbuf"));
 1437: 
 1438: 	/* get SP for this packet.
 1439: 	 * When we are called from ip_forward(), we call
 1440: 	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 1441: 	 */
 1442: 	if (inp == NULL)
 1443: 		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
 1444: 	else
 1445: 		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
 1446: 
 1447: 	if (sp != NULL) {
 1448: 		result = ipsec_in_reject(sp, m);
 1449: 		if (result)
 1450: 			newipsecstat.ips_in_polvio++;
 1451: 		KEY_FREESP(&sp);
 1452: 	} else {
 1453: 		result = 0;	/* XXX should be panic ?
 1454: 				 * -> No, there may be error. */
 1455: 	}
 1456: 	return result;
 1457: }
 1458: 
 1459: #ifdef INET6
 1460: /*
 1461:  * Check AH/ESP integrity.
 1462:  * This function is called from tcp6_input(), udp6_input(),
 1463:  * and {ah,esp}6_input for tunnel mode
 1464:  */
 1465: int
 1466: ipsec6_in_reject(m, inp)
 1467: 	struct mbuf *m;
 1468: 	struct inpcb *inp;
 1469: {
 1470: 	struct secpolicy *sp = NULL;
 1471: 	int error;
 1472: 	int result;
 1473: 
 1474: 	/* sanity check */
 1475: 	if (m == NULL)
 1476: 		return 0;	/* XXX should be panic ? */
 1477: 
 1478: 	/* get SP for this packet.
 1479: 	 * When we are called from ip_forward(), we call
 1480: 	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 1481: 	 */
 1482: 	if (inp == NULL)
 1483: 		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
 1484: 	else
 1485: 		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
 1486: 
 1487: 	if (sp != NULL) {
 1488: 		result = ipsec_in_reject(sp, m);
 1489: 		if (result)
 1490: 			newipsecstat.ips_in_polvio++;
 1491: 		KEY_FREESP(&sp);
 1492: 	} else {
 1493: 		result = 0;
 1494: 	}
 1495: 	return result;
 1496: }
 1497: #endif
 1498: 
 1499: /*
 1500:  * compute the byte size to be occupied by IPsec header.
 1501:  * in case it is tunneled, it includes the size of outer IP header.
 1502:  * NOTE: SP passed is free in this function.
 1503:  */
 1504: static size_t
 1505: ipsec_hdrsiz(struct secpolicy *sp)
 1506: {
 1507: 	struct ipsecrequest *isr;
 1508: 	size_t siz;
 1509: 
 1510: 	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1511: 		printf("ipsec_hdrsiz: using SP\n");
 1512: 		kdebug_secpolicy(sp));
 1513: 
 1514: 	switch (sp->policy) {
 1515: 	case IPSEC_POLICY_DISCARD:
 1516: 	case IPSEC_POLICY_BYPASS:
 1517: 	case IPSEC_POLICY_NONE:
 1518: 		return 0;
 1519: 	}
 1520: 
 1521: 	KASSERT(sp->policy == IPSEC_POLICY_IPSEC,
 1522: 		("ipsec_hdrsiz: invalid policy %u", sp->policy));
 1523: 
 1524: 	siz = 0;
 1525: 	for (isr = sp->req; isr != NULL; isr = isr->next) {
 1526: 		size_t clen = 0;
 1527: 
 1528: 		switch (isr->saidx.proto) {
 1529: 		case IPPROTO_ESP:
 1530: 			clen = esp_hdrsiz(isr->sav);
 1531: 			break;
 1532: 		case IPPROTO_AH:
 1533: 			clen = ah_hdrsiz(isr->sav);
 1534: 			break;
 1535: 		case IPPROTO_IPCOMP:
 1536: 			clen = sizeof(struct ipcomp);
 1537: 			break;
 1538: 		}
 1539: 
 1540: 		if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
 1541: 			switch (isr->saidx.dst.sa.sa_family) {
 1542: 			case AF_INET:
 1543: 				clen += sizeof(struct ip);
 1544: 				break;
 1545: #ifdef INET6
 1546: 			case AF_INET6:
 1547: 				clen += sizeof(struct ip6_hdr);
 1548: 				break;
 1549: #endif
 1550: 			default:
 1551: 				ipseclog((LOG_ERR, "ipsec_hdrsiz: "
 1552: 				    "unknown AF %d in IPsec tunnel SA\n",
 1553: 				    ((struct sockaddr *)&isr->saidx.dst)->sa_family));
 1554: 				break;
 1555: 			}
 1556: 		}
 1557: 		siz += clen;
 1558: 	}
 1559: 
 1560: 	return siz;
 1561: }
 1562: 
 1563: /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
 1564: size_t
 1565: ipsec4_hdrsiz(m, dir, inp)
 1566: 	struct mbuf *m;
 1567: 	u_int dir;
 1568: 	struct inpcb *inp;
 1569: {
 1570: 	struct secpolicy *sp;
 1571: 	int error;
 1572: 	size_t size;
 1573: 
 1574: 	KASSERT(m != NULL, ("ipsec4_hdrsiz: null mbuf"));
 1575: 	KASSERT(inp == NULL || inp->inp_socket != NULL,
 1576: 		("ipsec4_hdrsize: socket w/o inpcb"));
 1577: 
 1578: 	/* get SP for this packet.
 1579: 	 * When we are called from ip_forward(), we call
 1580: 	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 1581: 	 */
 1582: 	if (inp == NULL)
 1583: 		sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 1584: 	else
 1585: 		sp = ipsec_getpolicybysock(m, dir, inp, &error);
 1586: 
 1587: 	if (sp != NULL) {
 1588: 		size = ipsec_hdrsiz(sp);
 1589: 		KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1590: 			printf("ipsec4_hdrsiz: size:%lu.\n",
 1591: 				(unsigned long)size));
 1592: 
 1593: 		KEY_FREESP(&sp);
 1594: 	} else {
 1595: 		size = 0;	/* XXX should be panic ? */
 1596: 	}
 1597: 	return size;
 1598: }
 1599: 
 1600: #ifdef INET6
 1601: /* This function is called from ipsec6_hdrsize_tcp(),
 1602:  * and maybe from ip6_forward.()
 1603:  */
 1604: size_t
 1605: ipsec6_hdrsiz(m, dir, in6p)
 1606: 	struct mbuf *m;
 1607: 	u_int dir;
 1608: 	struct in6pcb *in6p;
 1609: {
 1610: 	struct secpolicy *sp;
 1611: 	int error;
 1612: 	size_t size;
 1613: 
 1614: 	KASSERT(m != NULL, ("ipsec6_hdrsiz: null mbuf"));
 1615: 	KASSERT(in6p == NULL || in6p->in6p_socket != NULL,
 1616: 		("ipsec6_hdrsize: socket w/o inpcb"));
 1617: 
 1618: 	/* get SP for this packet */
 1619: 	/* XXX Is it right to call with IP_FORWARDING. */
 1620: 	if (in6p == NULL)
 1621: 		sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 1622: 	else
 1623: 		sp = ipsec_getpolicybysock(m, dir, in6p, &error);
 1624: 
 1625: 	if (sp == NULL)
 1626: 		return 0;
 1627: 	size = ipsec_hdrsiz(sp);
 1628: 	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 1629: 		printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
 1630: 	KEY_FREESP(&sp);
 1631: 
 1632: 	return size;
 1633: }
 1634: #endif /*INET6*/
 1635: 
 1636: /*
 1637:  * Check the variable replay window.
 1638:  * ipsec_chkreplay() performs replay check before ICV verification.
 1639:  * ipsec_updatereplay() updates replay bitmap.  This must be called after
 1640:  * ICV verification (it also performs replay check, which is usually done
 1641:  * beforehand).
 1642:  * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
 1643:  *
 1644:  * based on RFC 2401.
 1645:  */
 1646: int
 1647: ipsec_chkreplay(seq, sav)
 1648: 	u_int32_t seq;
 1649: 	struct secasvar *sav;
 1650: {
 1651: 	const struct secreplay *replay;
 1652: 	u_int32_t diff;
 1653: 	int fr;
 1654: 	u_int32_t wsizeb;	/* constant: bits of window size */
 1655: 	int frlast;		/* constant: last frame */
 1656: 
 1657: 	SPLASSERT(net, "ipsec_chkreplay");
 1658: 
 1659: 	KASSERT(sav != NULL, ("ipsec_chkreplay: Null SA"));
 1660: 	KASSERT(sav->replay != NULL, ("ipsec_chkreplay: Null replay state"));
 1661: 
 1662: 	replay = sav->replay;
 1663: 
 1664: 	if (replay->wsize == 0)
 1665: 		return 1;	/* no need to check replay. */
 1666: 
 1667: 	/* constant */
 1668: 	frlast = replay->wsize - 1;
 1669: 	wsizeb = replay->wsize << 3;
 1670: 
 1671: 	/* sequence number of 0 is invalid */
 1672: 	if (seq == 0)
 1673: 		return 0;
 1674: 
 1675: 	/* first time is always okay */
 1676: 	if (replay->count == 0)
 1677: 		return 1;
 1678: 
 1679: 	if (seq > replay->lastseq) {
 1680: 		/* larger sequences are okay */
 1681: 		return 1;
 1682: 	} else {
 1683: 		/* seq is equal or less than lastseq. */
 1684: 		diff = replay->lastseq - seq;
 1685: 
 1686: 		/* over range to check, i.e. too old or wrapped */
 1687: 		if (diff >= wsizeb)
 1688: 			return 0;
 1689: 
 1690: 		fr = frlast - diff / 8;
 1691: 
 1692: 		/* this packet already seen ? */
 1693: 		if ((replay->bitmap)[fr] & (1 << (diff % 8)))
 1694: 			return 0;
 1695: 
 1696: 		/* out of order but good */
 1697: 		return 1;
 1698: 	}
 1699: }
 1700: 
 1701: /*
 1702:  * check replay counter whether to update or not.
 1703:  * OUT:	0:	OK
 1704:  *	1:	NG
 1705:  */
 1706: int
 1707: ipsec_updatereplay(seq, sav)
 1708: 	u_int32_t seq;
 1709: 	struct secasvar *sav;
 1710: {
 1711: 	struct secreplay *replay;
 1712: 	u_int32_t diff;
 1713: 	int fr;
 1714: 	u_int32_t wsizeb;	/* constant: bits of window size */
 1715: 	int frlast;		/* constant: last frame */
 1716: 
 1717: 	SPLASSERT(net, "ipsec_updatereplay");
 1718: 
 1719: 	KASSERT(sav != NULL, ("ipsec_updatereplay: Null SA"));
 1720: 	KASSERT(sav->replay != NULL, ("ipsec_updatereplay: Null replay state"));
 1721: 
 1722: 	replay = sav->replay;
 1723: 
 1724: 	if (replay->wsize == 0)
 1725: 		goto ok;	/* no need to check replay. */
 1726: 
 1727: 	/* constant */
 1728: 	frlast = replay->wsize - 1;
 1729: 	wsizeb = replay->wsize << 3;
 1730: 
 1731: 	/* sequence number of 0 is invalid */
 1732: 	if (seq == 0)
 1733: 		return 1;
 1734: 
 1735: 	/* first time */
 1736: 	if (replay->count == 0) {
 1737: 		replay->lastseq = seq;
 1738: 		bzero(replay->bitmap, replay->wsize);
 1739: 		(replay->bitmap)[frlast] = 1;
 1740: 		goto ok;
 1741: 	}
 1742: 
 1743: 	if (seq > replay->lastseq) {
 1744: 		/* seq is larger than lastseq. */
 1745: 		diff = seq - replay->lastseq;
 1746: 
 1747: 		/* new larger sequence number */
 1748: 		if (diff < wsizeb) {
 1749: 			/* In window */
 1750: 			/* set bit for this packet */
 1751: 			vshiftl(replay->bitmap, diff, replay->wsize);
 1752: 			(replay->bitmap)[frlast] |= 1;
 1753: 		} else {
 1754: 			/* this packet has a "way larger" */
 1755: 			bzero(replay->bitmap, replay->wsize);
 1756: 			(replay->bitmap)[frlast] = 1;
 1757: 		}
 1758: 		replay->lastseq = seq;
 1759: 
 1760: 		/* larger is good */
 1761: 	} else {
 1762: 		/* seq is equal or less than lastseq. */
 1763: 		diff = replay->lastseq - seq;
 1764: 
 1765: 		/* over range to check, i.e. too old or wrapped */
 1766: 		if (diff >= wsizeb)
 1767: 			return 1;
 1768: 
 1769: 		fr = frlast - diff / 8;
 1770: 
 1771: 		/* this packet already seen ? */
 1772: 		if ((replay->bitmap)[fr] & (1 << (diff % 8)))
 1773: 			return 1;
 1774: 
 1775: 		/* mark as seen */
 1776: 		(replay->bitmap)[fr] |= (1 << (diff % 8));
 1777: 
 1778: 		/* out of order but good */
 1779: 	}
 1780: 
 1781: ok:
 1782: 	if (replay->count == ~0) {
 1783: 
 1784: 		/* set overflow flag */
 1785: 		replay->overflow++;
 1786: 
 1787: 		/* don't increment, no more packets accepted */
 1788: 		if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
 1789: 			return 1;
 1790: 
 1791: 		ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
 1792: 		    replay->overflow, ipsec_logsastr(sav)));
 1793: 	}
 1794: 
 1795: 	replay->count++;
 1796: 
 1797: 	return 0;
 1798: }
 1799: 
 1800: /*
 1801:  * shift variable length bunffer to left.
 1802:  * IN:	bitmap: pointer to the buffer
 1803:  * 	nbit:	the number of to shift.
 1804:  *	wsize:	buffer size (bytes).
 1805:  */
 1806: static void
 1807: vshiftl(bitmap, nbit, wsize)
 1808: 	unsigned char *bitmap;
 1809: 	int nbit, wsize;
 1810: {
 1811: 	int s, j, i;
 1812: 	unsigned char over;
 1813: 
 1814: 	for (j = 0; j < nbit; j += 8) {
 1815: 		s = (nbit - j < 8) ? (nbit - j): 8;
 1816: 		bitmap[0] <<= s;
 1817: 		for (i = 1; i < wsize; i++) {
 1818: 			over = (bitmap[i] >> (8 - s));
 1819: 			bitmap[i] <<= s;
 1820: 			bitmap[i-1] |= over;
 1821: 		}
 1822: 	}
 1823: 
 1824: 	return;
 1825: }
 1826: 
 1827: /* Return a printable string for the IPv4 address. */
 1828: static char *
 1829: inet_ntoa4(struct in_addr ina)
 1830: {
 1831: 	static char buf[4][4 * sizeof "123" + 4];
 1832: 	unsigned char *ucp = (unsigned char *) &ina;
 1833: 	static int i = 3;
 1834: 
 1835: 	i = (i + 1) % 4;
 1836: 	sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
 1837: 	    ucp[2] & 0xff, ucp[3] & 0xff);
 1838: 	return (buf[i]);
 1839: }
 1840: 
 1841: /* Return a printable string for the address. */
 1842: char *
 1843: ipsec_address(union sockaddr_union* sa)
 1844: {
 1845: 	switch (sa->sa.sa_family) {
 1846: #if INET
 1847: 	case AF_INET:
 1848: 		return inet_ntoa4(sa->sin.sin_addr);
 1849: #endif /* INET */
 1850: 
 1851: #if INET6
 1852: 	case AF_INET6:
 1853: 		return ip6_sprintf(&sa->sin6.sin6_addr);
 1854: #endif /* INET6 */
 1855: 
 1856: 	default:
 1857: 		return "(unknown address family)";
 1858: 	}
 1859: }
 1860: 
 1861: const char *
 1862: ipsec_logsastr(sav)
 1863: 	struct secasvar *sav;
 1864: {
 1865: 	static char buf[256];
 1866: 	char *p;
 1867: 	struct secasindex *saidx = &sav->sah->saidx;
 1868: 
 1869: 	KASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
 1870: 		("ipsec_logsastr: address family mismatch"));
 1871: 
 1872: 	p = buf;
 1873: 	snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
 1874: 	while (p && *p)
 1875: 		p++;
 1876: 	/* NB: only use ipsec_address on one address at a time */
 1877: 	snprintf(p, sizeof (buf) - (p - buf), "src=%s ",
 1878: 		ipsec_address(&saidx->src));
 1879: 	while (p && *p)
 1880: 		p++;
 1881: 	snprintf(p, sizeof (buf) - (p - buf), "dst=%s)",
 1882: 		ipsec_address(&saidx->dst));
 1883: 
 1884: 	return buf;
 1885: }
 1886: 
 1887: void
 1888: ipsec_dumpmbuf(m)
 1889: 	struct mbuf *m;
 1890: {
 1891: 	int totlen;
 1892: 	int i;
 1893: 	u_char *p;
 1894: 
 1895: 	totlen = 0;
 1896: 	printf("---\n");
 1897: 	while (m) {
 1898: 		p = mtod(m, u_char *);
 1899: 		for (i = 0; i < m->m_len; i++) {
 1900: 			printf("%02x ", p[i]);
 1901: 			totlen++;
 1902: 			if (totlen % 16 == 0)
 1903: 				printf("\n");
 1904: 		}
 1905: 		m = m->m_next;
 1906: 	}
 1907: 	if (totlen % 16 != 0)
 1908: 		printf("\n");
 1909: 	printf("---\n");
 1910: }
 1911: 
 1912: /* XXX this stuff doesn't belong here... */
 1913: 
 1914: static	struct xformsw* xforms = NULL;
 1915: 
 1916: /*
 1917:  * Register a transform; typically at system startup.
 1918:  */
 1919: void
 1920: xform_register(struct xformsw* xsp)
 1921: {
 1922: 	xsp->xf_next = xforms;
 1923: 	xforms = xsp;
 1924: }
 1925: 
 1926: /*
 1927:  * Initialize transform support in an sav.
 1928:  */
 1929: int
 1930: xform_init(struct secasvar *sav, int xftype)
 1931: {
 1932: 	struct xformsw *xsp;
 1933: 
 1934: 	for (xsp = xforms; xsp; xsp = xsp->xf_next)
 1935: 		if (xsp->xf_type == xftype)
 1936: 			return (*xsp->xf_init)(sav, xsp);
 1937: 	return EINVAL;
 1938: }