xref: /netbsd-src/sys/netipsec/ipsec_input.c (revision c9496f6b604074a9451a67df576a5b423068e71e)
1 /*	$NetBSD: ipsec_input.c,v 1.55 2018/01/24 14:28:13 maxv Exp $	*/
2 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $	*/
3 /*	$OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $	*/
4 
5 /*
6  * The authors of this code are John Ioannidis (ji@tla.org),
7  * Angelos D. Keromytis (kermit@csd.uch.gr) and
8  * Niels Provos (provos@physnet.uni-hamburg.de).
9  *
10  * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
11  * in November 1995.
12  *
13  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
14  * by Angelos D. Keromytis.
15  *
16  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
17  * and Niels Provos.
18  *
19  * Additional features in 1999 by Angelos D. Keromytis.
20  *
21  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
22  * Angelos D. Keromytis and Niels Provos.
23  * Copyright (c) 2001, Angelos D. Keromytis.
24  *
25  * Permission to use, copy, and modify this software with or without fee
26  * is hereby granted, provided that this entire notice is included in
27  * all copies of any software which is or includes a copy or
28  * modification of this software.
29  * You may use this code under the GNU public license if you so wish. Please
30  * contribute changes back to the authors under this freer than GPL license
31  * so that we may further the use of strong encryption without limitations to
32  * all.
33  *
34  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38  * PURPOSE.
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.55 2018/01/24 14:28:13 maxv Exp $");
43 
44 /*
45  * IPsec input processing.
46  */
47 
48 #if defined(_KERNEL_OPT)
49 #include "opt_inet.h"
50 #endif
51 
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/malloc.h>
55 #include <sys/mbuf.h>
56 #include <sys/domain.h>
57 #include <sys/protosw.h>
58 #include <sys/socket.h>
59 #include <sys/errno.h>
60 #include <sys/syslog.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/in_proto.h>
71 #include <netinet/udp.h>
72 #include <netinet/tcp.h>
73 
74 #include <netinet/ip6.h>
75 #ifdef INET6
76 #include <netinet6/ip6_var.h>
77 #include <netinet6/ip6_private.h>
78 #include <netinet6/scope6_var.h>
79 #endif
80 #include <netinet/in_pcb.h>
81 #ifdef INET6
82 #include <netinet/icmp6.h>
83 #endif
84 
85 #include <netipsec/ipsec.h>
86 #include <netipsec/ipsec_private.h>
87 #ifdef INET6
88 #include <netipsec/ipsec6.h>
89 #endif
90 #include <netipsec/ah_var.h>
91 #include <netipsec/esp.h>
92 #include <netipsec/esp_var.h>
93 #include <netipsec/ipcomp_var.h>
94 
95 #include <netipsec/key.h>
96 #include <netipsec/keydb.h>
97 
98 #include <netipsec/xform.h>
99 #include <netinet6/ip6protosw.h>
100 
101 #include <net/net_osdep.h>
102 
103 #define	IPSEC_ISTAT(p, x, y, z)						\
104 do {									\
105 	switch (p) {							\
106 	case IPPROTO_ESP:						\
107 		ESP_STATINC(x);						\
108 		break;							\
109 	case IPPROTO_AH:						\
110 		AH_STATINC(y);						\
111 		break;							\
112 	default:							\
113 		IPCOMP_STATINC(z);					\
114 		break;							\
115 	}								\
116 } while (/*CONSTCOND*/0)
117 
118 /*
119  * fixup TCP/UDP checksum
120  *
121  * XXX: if we have NAT-OA payload from IKE server,
122  *      we must do the differential update of checksum.
123  *
124  * XXX: NAT-OAi/NAT-OAr drived from IKE initiator/responder.
125  *      how to know the IKE side from kernel?
126  */
127 static struct mbuf *
128 ipsec4_fixup_checksum(struct mbuf *m)
129 {
130 	struct ip *ip;
131 	struct tcphdr *th;
132 	struct udphdr *uh;
133 	int poff, off;
134 	int plen;
135 
136 	if (m->m_len < sizeof(*ip)) {
137 		m = m_pullup(m, sizeof(*ip));
138 		if (m == NULL)
139 			return NULL;
140 	}
141 	ip = mtod(m, struct ip *);
142 	poff = ip->ip_hl << 2;
143 	plen = ntohs(ip->ip_len) - poff;
144 
145 	switch (ip->ip_p) {
146 	case IPPROTO_TCP:
147 		IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
148 		if (th == NULL)
149 			return NULL;
150 		off = th->th_off << 2;
151 		if (off < sizeof(*th) || off > plen) {
152 			m_freem(m);
153 			return NULL;
154 		}
155 		th->th_sum = 0;
156 		th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
157 		break;
158 	case IPPROTO_UDP:
159 		IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
160 		if (uh == NULL)
161 			return NULL;
162 		off = sizeof(*uh);
163 		if (off > plen) {
164 			m_freem(m);
165 			return NULL;
166 		}
167 		uh->uh_sum = 0;
168 		uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
169 		break;
170 	default:
171 		/* no checksum */
172 		return m;
173 	}
174 
175 	return m;
176 }
177 
178 /*
179  * ipsec_common_input gets called when an IPsec-protected packet
180  * is received by IPv4 or IPv6.  It's job is to find the right SA
181  # and call the appropriate transform.  The transform callback
182  * takes care of further processing (like ingress filtering).
183  */
184 static int
185 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
186 {
187 	char buf[IPSEC_ADDRSTRLEN];
188 	union sockaddr_union dst_address;
189 	struct secasvar *sav;
190 	u_int32_t spi;
191 	u_int16_t sport;
192 	u_int16_t dport;
193 	int s, error;
194 
195 	IPSEC_ISTAT(sproto, ESP_STAT_INPUT, AH_STAT_INPUT,
196 		IPCOMP_STAT_INPUT);
197 
198 	KASSERT(m != NULL);
199 
200 	if ((sproto == IPPROTO_ESP && !esp_enable) ||
201 	    (sproto == IPPROTO_AH && !ah_enable) ||
202 	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
203 		m_freem(m);
204 		IPSEC_ISTAT(sproto, ESP_STAT_PDROPS, AH_STAT_PDROPS,
205 		    IPCOMP_STAT_PDROPS);
206 		return EOPNOTSUPP;
207 	}
208 
209 	if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) {
210 		m_freem(m);
211 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
212 		    IPCOMP_STAT_HDROPS);
213 		IPSECLOG(LOG_DEBUG, "packet too small\n");
214 		return EINVAL;
215 	}
216 
217 	/* Retrieve the SPI from the relevant IPsec header */
218 	if (sproto == IPPROTO_ESP)
219 		m_copydata(m, skip, sizeof(u_int32_t), &spi);
220 	else if (sproto == IPPROTO_AH)
221 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), &spi);
222 	else if (sproto == IPPROTO_IPCOMP) {
223 		u_int16_t cpi;
224 		m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), &cpi);
225 		spi = ntohl(htons(cpi));
226 	} else {
227 		panic("ipsec_common_input called with bad protocol number :"
228 		      "%d\n", sproto);
229 	}
230 
231 
232 	/* find the source port for NAT-T */
233 	nat_t_ports_get(m, &dport, &sport);
234 
235 	/*
236 	 * Find the SA and (indirectly) call the appropriate
237 	 * kernel crypto routine. The resulting mbuf chain is a valid
238 	 * IP packet ready to go through input processing.
239 	 */
240 	memset(&dst_address, 0, sizeof (dst_address));
241 	dst_address.sa.sa_family = af;
242 	switch (af) {
243 #ifdef INET
244 	case AF_INET:
245 		dst_address.sin.sin_len = sizeof(struct sockaddr_in);
246 		m_copydata(m, offsetof(struct ip, ip_dst),
247 		    sizeof(struct in_addr),
248 		    &dst_address.sin.sin_addr);
249 		break;
250 #endif /* INET */
251 #ifdef INET6
252 	case AF_INET6:
253 		dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
254 		m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
255 		    sizeof(struct in6_addr),
256 		    &dst_address.sin6.sin6_addr);
257 		if (sa6_recoverscope(&dst_address.sin6)) {
258 			m_freem(m);
259 			return EINVAL;
260 		}
261 		break;
262 #endif /* INET6 */
263 	default:
264 		IPSECLOG(LOG_DEBUG, "unsupported protocol family %u\n", af);
265 		m_freem(m);
266 		IPSEC_ISTAT(sproto, ESP_STAT_NOPF, AH_STAT_NOPF,
267 		    IPCOMP_STAT_NOPF);
268 		return EPFNOSUPPORT;
269 	}
270 
271 	s = splsoftnet();
272 
273 	/* NB: only pass dst since key_lookup_sa follows RFC2401 */
274 	sav = KEY_LOOKUP_SA(&dst_address, sproto, spi, sport, dport);
275 	if (sav == NULL) {
276 		IPSECLOG(LOG_DEBUG,
277 		    "no key association found for SA %s/%08lx/%u/%u\n",
278 		    ipsec_address(&dst_address, buf, sizeof(buf)),
279 		    (u_long) ntohl(spi), sproto, ntohs(dport));
280 		IPSEC_ISTAT(sproto, ESP_STAT_NOTDB, AH_STAT_NOTDB,
281 		    IPCOMP_STAT_NOTDB);
282 		splx(s);
283 		m_freem(m);
284 		return ENOENT;
285 	}
286 
287 	KASSERT(sav->tdb_xform != NULL);
288 
289 	/*
290 	 * Call appropriate transform and return -- callback takes care of
291 	 * everything else.
292 	 */
293 	error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
294 	KEY_SA_UNREF(&sav);
295 	splx(s);
296 	return error;
297 }
298 
299 #ifdef INET
300 /*
301  * Common input handler for IPv4 AH, ESP, and IPCOMP.
302  */
303 void
304 ipsec4_common_input(struct mbuf *m, ...)
305 {
306 	va_list ap;
307 	int off, nxt;
308 
309 	va_start(ap, m);
310 	off = va_arg(ap, int);
311 	nxt = va_arg(ap, int);
312 	va_end(ap);
313 
314 	(void) ipsec_common_input(m, off, offsetof(struct ip, ip_p),
315 				  AF_INET, nxt);
316 }
317 
318 /*
319  * IPsec input callback for INET protocols.
320  * This routine is called as the transform callback.
321  * Takes care of filtering and other sanity checks on
322  * the processed packet.
323  */
324 int
325 ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
326     int skip, int protoff)
327 {
328 	int prot, af __diagused, sproto;
329 	struct ip *ip;
330 	struct secasindex *saidx;
331 	int error;
332 
333 	IPSEC_SPLASSERT_SOFTNET("ipsec4_common_input_cb");
334 
335 	KASSERT(m != NULL);
336 	KASSERT(sav != NULL);
337 	saidx = &sav->sah->saidx;
338 	af = saidx->dst.sa.sa_family;
339 	KASSERTMSG(af == AF_INET, "unexpected af %u", af);
340 	sproto = saidx->proto;
341 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
342 	    sproto == IPPROTO_IPCOMP,
343 	    "unexpected security protocol %u", sproto);
344 
345 	/* Sanity check */
346 	if (m == NULL) {
347 		IPSECLOG(LOG_DEBUG, "null mbuf");
348 		IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
349 		    IPCOMP_STAT_BADKCR);
350 		return EINVAL;
351 	}
352 
353 	/* Fix IPv4 header */
354 	if (skip != 0) {
355 		if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
356 			char buf[IPSEC_ADDRSTRLEN];
357 cantpull:
358 			IPSECLOG(LOG_DEBUG,
359 			    "processing failed for SA %s/%08lx\n",
360 			    ipsec_address(&sav->sah->saidx.dst, buf,
361 			    sizeof(buf)), (u_long) ntohl(sav->spi));
362 			IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
363 			    IPCOMP_STAT_HDROPS);
364 			error = ENOBUFS;
365 			goto bad;
366 		}
367 
368 		ip = mtod(m, struct ip *);
369 		ip->ip_len = htons(m->m_pkthdr.len);
370 		ip->ip_sum = 0;
371 		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
372 	} else {
373 		/* XXX this branch is never taken */
374 		ip = mtod(m, struct ip *);
375 	}
376 
377 	/*
378 	 * Update TCP/UDP checksum
379 	 * XXX: should only do it in NAT-T case
380 	 * XXX: should do it incrementally, see FreeBSD code.
381 	 */
382 	m = ipsec4_fixup_checksum(m);
383 	if (m == NULL)
384 		goto cantpull;
385 	ip = mtod(m, struct ip *);
386 
387 	prot = ip->ip_p;
388 
389 	/* IP-in-IP encapsulation */
390 	if (prot == IPPROTO_IPIP) {
391 		struct ip ipn;
392 
393 		/* ipn will now contain the inner IPv4 header */
394 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), &ipn);
395 
396 #ifdef notyet
397 		/* XXX PROXY address isn't recorded in SAH */
398 		/*
399 		 * Check that the inner source address is the same as
400 		 * the proxy address, if available.
401 		 */
402 		if ((saidx->proxy.sa.sa_family == AF_INET &&
403 		    saidx->proxy.sin.sin_addr.s_addr !=
404 		    INADDR_ANY &&
405 		    ipn.ip_src.s_addr !=
406 		    saidx->proxy.sin.sin_addr.s_addr) ||
407 		    (saidx->proxy.sa.sa_family != AF_INET &&
408 			saidx->proxy.sa.sa_family != 0)) {
409 
410 			char ipbuf[INET_ADDRSTRLEN];
411 			IPSECLOG(LOG_DEBUG,
412 			    "inner source address %s doesn't correspond to "
413 			    "expected proxy source %s, SA %s/%08lx\n",
414 			    IN_PRINT(ipbuf, ipn.ip_src),
415 			    ipsp_address(saidx->proxy),
416 			    ipsp_address(saidx->dst),
417 			    (u_long) ntohl(sav->spi));
418 
419 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
420 			    AH_STAT_PDROPS,
421 			    IPCOMP_STAT_PDROPS);
422 			error = EACCES;
423 			goto bad;
424 		}
425 #endif /*XXX*/
426 	}
427 #if INET6
428 	/* IPv6-in-IP encapsulation. */
429 	if (prot == IPPROTO_IPV6) {
430 		struct ip6_hdr ip6n;
431 
432 		/* ip6n will now contain the inner IPv6 header. */
433 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), &ip6n);
434 
435 #ifdef notyet
436 		/*
437 		 * Check that the inner source address is the same as
438 		 * the proxy address, if available.
439 		 */
440 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
441 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
442 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
443 			&saidx->proxy.sin6.sin6_addr)) ||
444 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
445 			saidx->proxy.sa.sa_family != 0)) {
446 
447 			char ip6buf[INET6_ADDRSTRLEN];
448 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
449 			IPSECLOG(LOG_DEBUG,
450 			    "inner source address %s doesn't correspond to "
451 			    "expected proxy source %s, SA %s/%08lx\n",
452 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
453 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
454 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
455 			    (u_long) ntohl(sav->spi));
456 
457 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
458 			    AH_STAT_PDROPS,
459 			    IPCOMP_STAT_PDROPS);
460 			error = EACCES;
461 			goto bad;
462 		}
463 #endif /*XXX*/
464 	}
465 #endif /* INET6 */
466 
467 	key_sa_recordxfer(sav, m);		/* record data transfer */
468 
469 	if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 &&
470 				ipsec4_in_reject(m, NULL)) {
471 		error = EINVAL;
472 		goto bad;
473 	}
474 	(*inetsw[ip_protox[prot]].pr_input)(m, skip, prot);
475 	return 0;
476 bad:
477 	m_freem(m);
478 	return error;
479 }
480 #endif /* INET */
481 
482 #ifdef INET6
483 /* IPv6 AH wrapper. */
484 int
485 ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
486 {
487 	int l = 0;
488 	int protoff, nxt;
489 	struct ip6_ext ip6e;
490 
491 	if (*offp < sizeof(struct ip6_hdr)) {
492 		IPSECLOG(LOG_DEBUG, "bad offset %u\n", *offp);
493 		IPSEC_ISTAT(proto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
494 			    IPCOMP_STAT_HDROPS);
495 		m_freem(*mp);
496 		return IPPROTO_DONE;
497 	} else if (*offp == sizeof(struct ip6_hdr)) {
498 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
499 	} else {
500 		/* Chase down the header chain... */
501 		protoff = sizeof(struct ip6_hdr);
502 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
503 
504 		do {
505 			protoff += l;
506 			m_copydata(*mp, protoff, sizeof(ip6e), &ip6e);
507 
508 			if (nxt == IPPROTO_AH)
509 				l = (ip6e.ip6e_len + 2) << 2;
510 			else if (nxt == IPPROTO_FRAGMENT)
511 				l = sizeof(struct ip6_frag);
512 			else
513 				l = (ip6e.ip6e_len + 1) << 3;
514 			KASSERT(l > 0);
515 
516 			nxt = ip6e.ip6e_nxt;
517 		} while (protoff + l < *offp);
518 
519 		/* Malformed packet check */
520 		if (protoff + l != *offp) {
521 			IPSECLOG(LOG_DEBUG, "bad packet header chain, "
522 			    "protoff %u, l %u, off %u\n", protoff, l, *offp);
523 			IPSEC_ISTAT(proto, ESP_STAT_HDROPS,
524 				    AH_STAT_HDROPS,
525 				    IPCOMP_STAT_HDROPS);
526 			m_freem(*mp);
527 			*mp = NULL;
528 			return IPPROTO_DONE;
529 		}
530 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
531 	}
532 	(void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
533 	return IPPROTO_DONE;
534 }
535 
536 extern	const struct ip6protosw inet6sw[];
537 extern	u_char ip6_protox[];
538 
539 /*
540  * IPsec input callback, called by the transform callback. Takes care of
541  * filtering and other sanity checks on the processed packet.
542  */
543 int
544 ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
545     int protoff)
546 {
547 	int af __diagused, sproto;
548 	struct ip6_hdr *ip6;
549 	struct secasindex *saidx;
550 	int nxt;
551 	u_int8_t prot, nxt8;
552 	int error, nest;
553 
554 	KASSERT(m != NULL);
555 	KASSERT(sav != NULL);
556 	saidx = &sav->sah->saidx;
557 	af = saidx->dst.sa.sa_family;
558 	KASSERTMSG(af == AF_INET6, "unexpected af %u", af);
559 	sproto = saidx->proto;
560 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
561 	    sproto == IPPROTO_IPCOMP,
562 	    "unexpected security protocol %u", sproto);
563 
564 	/* Sanity check */
565 	if (m == NULL) {
566 		IPSECLOG(LOG_DEBUG, "null mbuf");
567 		IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
568 		    IPCOMP_STAT_BADKCR);
569 		error = EINVAL;
570 		goto bad;
571 	}
572 
573 	/* Fix IPv6 header */
574 	if (m->m_len < sizeof(struct ip6_hdr) &&
575 	    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
576 
577 		char buf[IPSEC_ADDRSTRLEN];
578 		IPSECLOG(LOG_DEBUG, "processing failed for SA %s/%08lx\n",
579 		    ipsec_address(&sav->sah->saidx.dst,
580 		    buf, sizeof(buf)), (u_long) ntohl(sav->spi));
581 
582 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
583 		    IPCOMP_STAT_HDROPS);
584 		error = EACCES;
585 		goto bad;
586 	}
587 
588 	ip6 = mtod(m, struct ip6_hdr *);
589 	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
590 
591 	/* Save protocol */
592 	m_copydata(m, protoff, 1, &prot);
593 
594 #ifdef INET
595 	/* IP-in-IP encapsulation */
596 	if (prot == IPPROTO_IPIP) {
597 		struct ip ipn;
598 
599 		/* ipn will now contain the inner IPv4 header */
600 		m_copydata(m, skip, sizeof(struct ip), &ipn);
601 
602 #ifdef notyet
603 		/*
604 		 * Check that the inner source address is the same as
605 		 * the proxy address, if available.
606 		 */
607 		if ((saidx->proxy.sa.sa_family == AF_INET &&
608 		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
609 		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
610 		    (saidx->proxy.sa.sa_family != AF_INET &&
611 			saidx->proxy.sa.sa_family != 0)) {
612 
613 			char ipbuf[INET_ADDRSTRLEN];
614 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
615 			IPSECLOG(LOG_DEBUG,
616 			    "inner source address %s doesn't correspond to "
617 			    "expected proxy source %s, SA %s/%08lx\n",
618 			    IN_PRINT(ipbuf, ipn.ip_src),
619 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
620 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
621 			    (u_long) ntohl(sav->spi));
622 
623 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
624 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
625 			error = EACCES;
626 			goto bad;
627 		}
628 #endif /*XXX*/
629 	}
630 #endif /* INET */
631 
632 	/* IPv6-in-IP encapsulation */
633 	if (prot == IPPROTO_IPV6) {
634 		struct ip6_hdr ip6n;
635 
636 		/* ip6n will now contain the inner IPv6 header. */
637 		m_copydata(m, skip, sizeof(struct ip6_hdr), &ip6n);
638 
639 #ifdef notyet
640 		/*
641 		 * Check that the inner source address is the same as
642 		 * the proxy address, if available.
643 		 */
644 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
645 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
646 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
647 			&saidx->proxy.sin6.sin6_addr)) ||
648 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
649 			saidx->proxy.sa.sa_family != 0)) {
650 
651 			char ip6buf[INET6_ADDRSTRLEN];
652 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
653 			IPSECLOG(LOG_DEBUG,
654 			    "inner source address %s doesn't correspond to "
655 			    "expected proxy source %s, SA %s/%08lx\n",
656 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
657 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
658 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
659 			    (u_long) ntohl(sav->spi));
660 
661 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
662 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
663 			error = EACCES;
664 			goto bad;
665 		}
666 #endif /*XXX*/
667 	}
668 
669 	key_sa_recordxfer(sav, m);
670 
671 	/* Retrieve new protocol */
672 	m_copydata(m, protoff, sizeof(u_int8_t), &nxt8);
673 
674 	/*
675 	 * See the end of ip6_input for this logic.
676 	 * IPPROTO_IPV[46] case will be processed just like other ones
677 	 */
678 	nest = 0;
679 	nxt = nxt8;
680 	while (nxt != IPPROTO_DONE) {
681 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
682 			IP6_STATINC(IP6_STAT_TOOMANYHDR);
683 			error = EINVAL;
684 			goto bad;
685 		}
686 
687 		/*
688 		 * Protection against faulty packet - there should be
689 		 * more sanity checks in header chain processing.
690 		 */
691 		if (m->m_pkthdr.len < skip) {
692 			IP6_STATINC(IP6_STAT_TOOSHORT);
693 			in6_ifstat_inc(m_get_rcvif_NOMPSAFE(m),
694 				       ifs6_in_truncated);
695 			error = EINVAL;
696 			goto bad;
697 		}
698 		/*
699 		 * Enforce IPsec policy checking if we are seeing last header.
700 		 * note that we do not visit this with protocols with pcb layer
701 		 * code - like udp/tcp/raw ip.
702 		 */
703 		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
704 		    ipsec6_in_reject(m, NULL)) {
705 			error = EINVAL;
706 			goto bad;
707 		}
708 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
709 	}
710 	return 0;
711 bad:
712 	if (m)
713 		m_freem(m);
714 	return error;
715 }
716 #endif /* INET6 */
717