xref: /netbsd-src/sys/netipsec/ipsec_input.c (revision 7c192b2a5e1093666e67801684f930ef49b3b363)
1 /*	$NetBSD: ipsec_input.c,v 1.49 2017/07/21 04:55:36 ozaki-r 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.49 2017/07/21 04:55:36 ozaki-r 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        ip = mtod(m, struct ip *);
139        poff = ip->ip_hl << 2;
140        plen = ntohs(ip->ip_len) - poff;
141 
142        switch (ip->ip_p) {
143        case IPPROTO_TCP:
144                IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
145                if (th == NULL)
146                        return NULL;
147                off = th->th_off << 2;
148                if (off < sizeof(*th) || off > plen) {
149                        m_freem(m);
150                        return NULL;
151                }
152                th->th_sum = 0;
153                th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
154                break;
155        case IPPROTO_UDP:
156                IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
157                if (uh == NULL)
158                        return NULL;
159                off = sizeof(*uh);
160                if (off > plen) {
161                        m_freem(m);
162                        return NULL;
163                }
164                uh->uh_sum = 0;
165                uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
166                break;
167        default:
168                /* no checksum */
169                return m;
170        }
171 
172        return m;
173 }
174 
175 /*
176  * ipsec_common_input gets called when an IPsec-protected packet
177  * is received by IPv4 or IPv6.  It's job is to find the right SA
178  # and call the appropriate transform.  The transform callback
179  * takes care of further processing (like ingress filtering).
180  */
181 static int
182 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
183 {
184 	char buf[IPSEC_ADDRSTRLEN];
185 	union sockaddr_union dst_address;
186 	struct secasvar *sav;
187 	u_int32_t spi;
188 	u_int16_t sport;
189 	u_int16_t dport;
190 	int s, error;
191 
192 	IPSEC_ISTAT(sproto, ESP_STAT_INPUT, AH_STAT_INPUT,
193 		IPCOMP_STAT_INPUT);
194 
195 	KASSERT(m != NULL);
196 
197 	if ((sproto == IPPROTO_ESP && !esp_enable) ||
198 	    (sproto == IPPROTO_AH && !ah_enable) ||
199 	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
200 		m_freem(m);
201 		IPSEC_ISTAT(sproto, ESP_STAT_PDROPS, AH_STAT_PDROPS,
202 		    IPCOMP_STAT_PDROPS);
203 		return EOPNOTSUPP;
204 	}
205 
206 	if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) {
207 		m_freem(m);
208 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
209 		    IPCOMP_STAT_HDROPS);
210 		IPSECLOG(LOG_DEBUG, "packet too small\n");
211 		return EINVAL;
212 	}
213 
214 	/* Retrieve the SPI from the relevant IPsec header */
215 	if (sproto == IPPROTO_ESP)
216 		m_copydata(m, skip, sizeof(u_int32_t), &spi);
217 	else if (sproto == IPPROTO_AH)
218 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), &spi);
219 	else if (sproto == IPPROTO_IPCOMP) {
220 		u_int16_t cpi;
221 		m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), &cpi);
222 		spi = ntohl(htons(cpi));
223 	} else {
224 		panic("ipsec_common_input called with bad protocol number :"
225 		      "%d\n", sproto);
226 	}
227 
228 
229 	/* find the source port for NAT-T */
230 	nat_t_ports_get(m, &dport, &sport);
231 
232 	/*
233 	 * Find the SA and (indirectly) call the appropriate
234 	 * kernel crypto routine. The resulting mbuf chain is a valid
235 	 * IP packet ready to go through input processing.
236 	 */
237 	memset(&dst_address, 0, sizeof (dst_address));
238 	dst_address.sa.sa_family = af;
239 	switch (af) {
240 #ifdef INET
241 	case AF_INET:
242 		dst_address.sin.sin_len = sizeof(struct sockaddr_in);
243 		m_copydata(m, offsetof(struct ip, ip_dst),
244 		    sizeof(struct in_addr),
245 		    &dst_address.sin.sin_addr);
246 		break;
247 #endif /* INET */
248 #ifdef INET6
249 	case AF_INET6:
250 		dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
251 		m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
252 		    sizeof(struct in6_addr),
253 		    &dst_address.sin6.sin6_addr);
254 		if (sa6_recoverscope(&dst_address.sin6)) {
255 			m_freem(m);
256 			return EINVAL;
257 		}
258 		break;
259 #endif /* INET6 */
260 	default:
261 		IPSECLOG(LOG_DEBUG, "unsupported protocol family %u\n", af);
262 		m_freem(m);
263 		IPSEC_ISTAT(sproto, ESP_STAT_NOPF, AH_STAT_NOPF,
264 		    IPCOMP_STAT_NOPF);
265 		return EPFNOSUPPORT;
266 	}
267 
268 	s = splsoftnet();
269 
270 	/* NB: only pass dst since key_lookup_sa follows RFC2401 */
271 	sav = KEY_LOOKUP_SA(&dst_address, sproto, spi, sport, dport);
272 	if (sav == NULL) {
273 		IPSECLOG(LOG_DEBUG,
274 		    "no key association found for SA %s/%08lx/%u/%u\n",
275 		    ipsec_address(&dst_address, buf, sizeof(buf)),
276 		    (u_long) ntohl(spi), sproto, ntohs(dport));
277 		IPSEC_ISTAT(sproto, ESP_STAT_NOTDB, AH_STAT_NOTDB,
278 		    IPCOMP_STAT_NOTDB);
279 		splx(s);
280 		m_freem(m);
281 		return ENOENT;
282 	}
283 
284 	KASSERT(sav->tdb_xform != NULL);
285 
286 	/*
287 	 * Call appropriate transform and return -- callback takes care of
288 	 * everything else.
289 	 */
290 	error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
291 	KEY_FREESAV(&sav);
292 	splx(s);
293 	return error;
294 }
295 
296 #ifdef INET
297 /*
298  * Common input handler for IPv4 AH, ESP, and IPCOMP.
299  */
300 void
301 ipsec4_common_input(struct mbuf *m, ...)
302 {
303 	va_list ap;
304 	int off, nxt;
305 
306 	va_start(ap, m);
307 	off = va_arg(ap, int);
308 	nxt = va_arg(ap, int);
309 	va_end(ap);
310 
311 	(void) ipsec_common_input(m, off, offsetof(struct ip, ip_p),
312 				  AF_INET, nxt);
313 }
314 
315 /*
316  * IPsec input callback for INET protocols.
317  * This routine is called as the transform callback.
318  * Takes care of filtering and other sanity checks on
319  * the processed packet.
320  */
321 int
322 ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
323     int skip, int protoff)
324 {
325 	int prot, af __diagused, sproto;
326 	struct ip *ip;
327 	struct secasindex *saidx;
328 	int error;
329 
330 	IPSEC_SPLASSERT_SOFTNET("ipsec4_common_input_cb");
331 
332 	KASSERT(m != NULL);
333 	KASSERT(sav != NULL);
334 	saidx = &sav->sah->saidx;
335 	af = saidx->dst.sa.sa_family;
336 	KASSERTMSG(af == AF_INET, "unexpected af %u", af);
337 	sproto = saidx->proto;
338 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
339 	    sproto == IPPROTO_IPCOMP,
340 	    "unexpected security protocol %u", sproto);
341 
342 	/* Sanity check */
343 	if (m == NULL) {
344 		IPSECLOG(LOG_DEBUG, "null mbuf");
345 		IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
346 		    IPCOMP_STAT_BADKCR);
347 		KEY_FREESAV(&sav);
348 		return EINVAL;
349 	}
350 
351 	/* Fix IPv4 header */
352 	if (skip != 0) {
353 		if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
354 			char buf[IPSEC_ADDRSTRLEN];
355 cantpull:
356 			IPSECLOG(LOG_DEBUG,
357 			    "processing failed for SA %s/%08lx\n",
358 			    ipsec_address(&sav->sah->saidx.dst, buf,
359 			    sizeof(buf)), (u_long) ntohl(sav->spi));
360 			IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
361 			    IPCOMP_STAT_HDROPS);
362 			error = ENOBUFS;
363 			goto bad;
364 		}
365 
366 		ip = mtod(m, struct ip *);
367 		ip->ip_len = htons(m->m_pkthdr.len);
368 		ip->ip_sum = 0;
369 		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
370 	} else {
371 		ip = mtod(m, struct ip *);
372 	}
373 
374 	/*
375 	 * Update TCP/UDP checksum
376 	 * XXX: should only do it in NAT-T case
377 	 * XXX: should do it incrementally, see FreeBSD code.
378 	 */
379 	m = ipsec4_fixup_checksum(m);
380 	if (m == NULL)
381 		goto cantpull;
382 
383 	prot = ip->ip_p;
384 
385 	/* IP-in-IP encapsulation */
386 	if (prot == IPPROTO_IPIP) {
387 		struct ip ipn;
388 
389 		/* ipn will now contain the inner IPv4 header */
390 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), &ipn);
391 
392 #ifdef notyet
393 		/* XXX PROXY address isn't recorded in SAH */
394 		/*
395 		 * Check that the inner source address is the same as
396 		 * the proxy address, if available.
397 		 */
398 		if ((saidx->proxy.sa.sa_family == AF_INET &&
399 		    saidx->proxy.sin.sin_addr.s_addr !=
400 		    INADDR_ANY &&
401 		    ipn.ip_src.s_addr !=
402 		    saidx->proxy.sin.sin_addr.s_addr) ||
403 		    (saidx->proxy.sa.sa_family != AF_INET &&
404 			saidx->proxy.sa.sa_family != 0)) {
405 
406 			char ipbuf[INET_ADDRSTRLEN];
407 			IPSECLOG(LOG_DEBUG,
408 			    "inner source address %s doesn't correspond to "
409 			    "expected proxy source %s, SA %s/%08lx\n",
410 			    IN_PRINT(ipbuf, ipn.ip_src),
411 			    ipsp_address(saidx->proxy),
412 			    ipsp_address(saidx->dst),
413 			    (u_long) ntohl(sav->spi));
414 
415 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
416 			    AH_STAT_PDROPS,
417 			    IPCOMP_STAT_PDROPS);
418 			error = EACCES;
419 			goto bad;
420 		}
421 #endif /*XXX*/
422 	}
423 #if INET6
424 	/* IPv6-in-IP encapsulation. */
425 	if (prot == IPPROTO_IPV6) {
426 		struct ip6_hdr ip6n;
427 
428 		/* ip6n will now contain the inner IPv6 header. */
429 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), &ip6n);
430 
431 #ifdef notyet
432 		/*
433 		 * Check that the inner source address is the same as
434 		 * the proxy address, if available.
435 		 */
436 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
437 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
438 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
439 			&saidx->proxy.sin6.sin6_addr)) ||
440 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
441 			saidx->proxy.sa.sa_family != 0)) {
442 
443 			char ip6buf[INET6_ADDRSTRLEN];
444 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
445 			IPSECLOG(LOG_DEBUG,
446 			    "inner source address %s doesn't correspond to "
447 			    "expected proxy source %s, SA %s/%08lx\n",
448 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
449 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
450 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
451 			    (u_long) ntohl(sav->spi));
452 
453 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
454 			    AH_STAT_PDROPS,
455 			    IPCOMP_STAT_PDROPS);
456 			error = EACCES;
457 			goto bad;
458 		}
459 #endif /*XXX*/
460 	}
461 #endif /* INET6 */
462 
463 	key_sa_recordxfer(sav, m);		/* record data transfer */
464 
465 	if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 &&
466 				ipsec4_in_reject(m, NULL)) {
467 		error = EINVAL;
468 		goto bad;
469 	}
470 	(*inetsw[ip_protox[prot]].pr_input)(m, skip, prot);
471 	return 0;
472 bad:
473 	m_freem(m);
474 	return error;
475 }
476 #endif /* INET */
477 
478 #ifdef INET6
479 /* IPv6 AH wrapper. */
480 int
481 ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
482 {
483 	int l = 0;
484 	int protoff, nxt;
485 	struct ip6_ext ip6e;
486 
487 	if (*offp < sizeof(struct ip6_hdr)) {
488 		IPSECLOG(LOG_DEBUG, "bad offset %u\n", *offp);
489 		IPSEC_ISTAT(proto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
490 			    IPCOMP_STAT_HDROPS);
491 		m_freem(*mp);
492 		return IPPROTO_DONE;
493 	} else if (*offp == sizeof(struct ip6_hdr)) {
494 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
495 	} else {
496 		/* Chase down the header chain... */
497 		protoff = sizeof(struct ip6_hdr);
498 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
499 
500 		do {
501 			protoff += l;
502 			m_copydata(*mp, protoff, sizeof(ip6e), &ip6e);
503 
504 			if (nxt == IPPROTO_AH)
505 				l = (ip6e.ip6e_len + 2) << 2;
506 			else
507 				l = (ip6e.ip6e_len + 1) << 3;
508 			KASSERT(l > 0);
509 
510 			nxt = ip6e.ip6e_nxt;
511 		} while (protoff + l < *offp);
512 
513 		/* Malformed packet check */
514 		if (protoff + l != *offp) {
515 			IPSECLOG(LOG_DEBUG, "bad packet header chain, "
516 			    "protoff %u, l %u, off %u\n", protoff, l, *offp);
517 			IPSEC_ISTAT(proto, ESP_STAT_HDROPS,
518 				    AH_STAT_HDROPS,
519 				    IPCOMP_STAT_HDROPS);
520 			m_freem(*mp);
521 			*mp = NULL;
522 			return IPPROTO_DONE;
523 		}
524 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
525 	}
526 	(void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
527 	return IPPROTO_DONE;
528 }
529 
530 extern	const struct ip6protosw inet6sw[];
531 extern	u_char ip6_protox[];
532 
533 /*
534  * IPsec input callback, called by the transform callback. Takes care of
535  * filtering and other sanity checks on the processed packet.
536  */
537 int
538 ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
539     int protoff)
540 {
541 	int af __diagused, sproto;
542 	struct ip6_hdr *ip6;
543 	struct secasindex *saidx;
544 	int nxt;
545 	u_int8_t prot, nxt8;
546 	int error, nest;
547 
548 	KASSERT(m != NULL);
549 	KASSERT(sav != NULL);
550 	saidx = &sav->sah->saidx;
551 	af = saidx->dst.sa.sa_family;
552 	KASSERTMSG(af == AF_INET6, "unexpected af %u", af);
553 	sproto = saidx->proto;
554 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
555 	    sproto == IPPROTO_IPCOMP,
556 	    "unexpected security protocol %u", sproto);
557 
558 	/* Sanity check */
559 	if (m == NULL) {
560 		IPSECLOG(LOG_DEBUG, "null mbuf");
561 		IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
562 		    IPCOMP_STAT_BADKCR);
563 		error = EINVAL;
564 		goto bad;
565 	}
566 
567 	/* Fix IPv6 header */
568 	if (m->m_len < sizeof(struct ip6_hdr) &&
569 	    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
570 
571 		char buf[IPSEC_ADDRSTRLEN];
572 		IPSECLOG(LOG_DEBUG, "processing failed for SA %s/%08lx\n",
573 		    ipsec_address(&sav->sah->saidx.dst,
574 		    buf, sizeof(buf)), (u_long) ntohl(sav->spi));
575 
576 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
577 		    IPCOMP_STAT_HDROPS);
578 		error = EACCES;
579 		goto bad;
580 	}
581 
582 	ip6 = mtod(m, struct ip6_hdr *);
583 	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
584 
585 	/* Save protocol */
586 	m_copydata(m, protoff, 1, &prot);
587 
588 #ifdef INET
589 	/* IP-in-IP encapsulation */
590 	if (prot == IPPROTO_IPIP) {
591 		struct ip ipn;
592 
593 		/* ipn will now contain the inner IPv4 header */
594 		m_copydata(m, skip, sizeof(struct ip), &ipn);
595 
596 #ifdef notyet
597 		/*
598 		 * Check that the inner source address is the same as
599 		 * the proxy address, if available.
600 		 */
601 		if ((saidx->proxy.sa.sa_family == AF_INET &&
602 		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
603 		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
604 		    (saidx->proxy.sa.sa_family != AF_INET &&
605 			saidx->proxy.sa.sa_family != 0)) {
606 
607 			char ipbuf[INET_ADDRSTRLEN];
608 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
609 			IPSECLOG(LOG_DEBUG,
610 			    "inner source address %s doesn't correspond to "
611 			    "expected proxy source %s, SA %s/%08lx\n",
612 			    IN_PRINT(ipbuf, ipn.ip_src),
613 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
614 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
615 			    (u_long) ntohl(sav->spi));
616 
617 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
618 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
619 			error = EACCES;
620 			goto bad;
621 		}
622 #endif /*XXX*/
623 	}
624 #endif /* INET */
625 
626 	/* IPv6-in-IP encapsulation */
627 	if (prot == IPPROTO_IPV6) {
628 		struct ip6_hdr ip6n;
629 
630 		/* ip6n will now contain the inner IPv6 header. */
631 		m_copydata(m, skip, sizeof(struct ip6_hdr), &ip6n);
632 
633 #ifdef notyet
634 		/*
635 		 * Check that the inner source address is the same as
636 		 * the proxy address, if available.
637 		 */
638 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
639 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
640 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
641 			&saidx->proxy.sin6.sin6_addr)) ||
642 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
643 			saidx->proxy.sa.sa_family != 0)) {
644 
645 			char ip6buf[INET6_ADDRSTRLEN];
646 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
647 			IPSECLOG(LOG_DEBUG,
648 			    "inner source address %s doesn't correspond to "
649 			    "expected proxy source %s, SA %s/%08lx\n",
650 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
651 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
652 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
653 			    (u_long) ntohl(sav->spi));
654 
655 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
656 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
657 			error = EACCES;
658 			goto bad;
659 		}
660 #endif /*XXX*/
661 	}
662 
663 	key_sa_recordxfer(sav, m);
664 
665 	/* Retrieve new protocol */
666 	m_copydata(m, protoff, sizeof(u_int8_t), &nxt8);
667 
668 	/*
669 	 * See the end of ip6_input for this logic.
670 	 * IPPROTO_IPV[46] case will be processed just like other ones
671 	 */
672 	nest = 0;
673 	nxt = nxt8;
674 	while (nxt != IPPROTO_DONE) {
675 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
676 			IP6_STATINC(IP6_STAT_TOOMANYHDR);
677 			error = EINVAL;
678 			goto bad;
679 		}
680 
681 		/*
682 		 * Protection against faulty packet - there should be
683 		 * more sanity checks in header chain processing.
684 		 */
685 		if (m->m_pkthdr.len < skip) {
686 			IP6_STATINC(IP6_STAT_TOOSHORT);
687 			in6_ifstat_inc(m_get_rcvif_NOMPSAFE(m),
688 				       ifs6_in_truncated);
689 			error = EINVAL;
690 			goto bad;
691 		}
692 		/*
693 		 * Enforce IPsec policy checking if we are seeing last header.
694 		 * note that we do not visit this with protocols with pcb layer
695 		 * code - like udp/tcp/raw ip.
696 		 */
697 		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
698 		    ipsec6_in_reject(m, NULL)) {
699 			error = EINVAL;
700 			goto bad;
701 		}
702 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
703 	}
704 	return 0;
705 bad:
706 	if (m)
707 		m_freem(m);
708 	return error;
709 }
710 #endif /* INET6 */
711