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