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

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

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