xref: /netbsd-src/sys/netipsec/ipsec_input.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /*	$NetBSD: ipsec_input.c,v 1.51 2017/08/03 06:32:51 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.51 2017/08/03 06:32:51 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_SA_UNREF(&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 		return EINVAL;
348 	}
349 
350 	/* Fix IPv4 header */
351 	if (skip != 0) {
352 		if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
353 			char buf[IPSEC_ADDRSTRLEN];
354 cantpull:
355 			IPSECLOG(LOG_DEBUG,
356 			    "processing failed for SA %s/%08lx\n",
357 			    ipsec_address(&sav->sah->saidx.dst, buf,
358 			    sizeof(buf)), (u_long) ntohl(sav->spi));
359 			IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
360 			    IPCOMP_STAT_HDROPS);
361 			error = ENOBUFS;
362 			goto bad;
363 		}
364 
365 		ip = mtod(m, struct ip *);
366 		ip->ip_len = htons(m->m_pkthdr.len);
367 		ip->ip_sum = 0;
368 		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
369 	} else {
370 		ip = mtod(m, struct ip *);
371 	}
372 
373 	/*
374 	 * Update TCP/UDP checksum
375 	 * XXX: should only do it in NAT-T case
376 	 * XXX: should do it incrementally, see FreeBSD code.
377 	 */
378 	m = ipsec4_fixup_checksum(m);
379 	if (m == NULL)
380 		goto cantpull;
381 
382 	prot = ip->ip_p;
383 
384 	/* IP-in-IP encapsulation */
385 	if (prot == IPPROTO_IPIP) {
386 		struct ip ipn;
387 
388 		/* ipn will now contain the inner IPv4 header */
389 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), &ipn);
390 
391 #ifdef notyet
392 		/* XXX PROXY address isn't recorded in SAH */
393 		/*
394 		 * Check that the inner source address is the same as
395 		 * the proxy address, if available.
396 		 */
397 		if ((saidx->proxy.sa.sa_family == AF_INET &&
398 		    saidx->proxy.sin.sin_addr.s_addr !=
399 		    INADDR_ANY &&
400 		    ipn.ip_src.s_addr !=
401 		    saidx->proxy.sin.sin_addr.s_addr) ||
402 		    (saidx->proxy.sa.sa_family != AF_INET &&
403 			saidx->proxy.sa.sa_family != 0)) {
404 
405 			char ipbuf[INET_ADDRSTRLEN];
406 			IPSECLOG(LOG_DEBUG,
407 			    "inner source address %s doesn't correspond to "
408 			    "expected proxy source %s, SA %s/%08lx\n",
409 			    IN_PRINT(ipbuf, ipn.ip_src),
410 			    ipsp_address(saidx->proxy),
411 			    ipsp_address(saidx->dst),
412 			    (u_long) ntohl(sav->spi));
413 
414 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
415 			    AH_STAT_PDROPS,
416 			    IPCOMP_STAT_PDROPS);
417 			error = EACCES;
418 			goto bad;
419 		}
420 #endif /*XXX*/
421 	}
422 #if INET6
423 	/* IPv6-in-IP encapsulation. */
424 	if (prot == IPPROTO_IPV6) {
425 		struct ip6_hdr ip6n;
426 
427 		/* ip6n will now contain the inner IPv6 header. */
428 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), &ip6n);
429 
430 #ifdef notyet
431 		/*
432 		 * Check that the inner source address is the same as
433 		 * the proxy address, if available.
434 		 */
435 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
436 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
437 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
438 			&saidx->proxy.sin6.sin6_addr)) ||
439 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
440 			saidx->proxy.sa.sa_family != 0)) {
441 
442 			char ip6buf[INET6_ADDRSTRLEN];
443 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
444 			IPSECLOG(LOG_DEBUG,
445 			    "inner source address %s doesn't correspond to "
446 			    "expected proxy source %s, SA %s/%08lx\n",
447 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
448 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
449 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
450 			    (u_long) ntohl(sav->spi));
451 
452 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
453 			    AH_STAT_PDROPS,
454 			    IPCOMP_STAT_PDROPS);
455 			error = EACCES;
456 			goto bad;
457 		}
458 #endif /*XXX*/
459 	}
460 #endif /* INET6 */
461 
462 	key_sa_recordxfer(sav, m);		/* record data transfer */
463 
464 	if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 &&
465 				ipsec4_in_reject(m, NULL)) {
466 		error = EINVAL;
467 		goto bad;
468 	}
469 	(*inetsw[ip_protox[prot]].pr_input)(m, skip, prot);
470 	return 0;
471 bad:
472 	m_freem(m);
473 	return error;
474 }
475 #endif /* INET */
476 
477 #ifdef INET6
478 /* IPv6 AH wrapper. */
479 int
480 ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
481 {
482 	int l = 0;
483 	int protoff, nxt;
484 	struct ip6_ext ip6e;
485 
486 	if (*offp < sizeof(struct ip6_hdr)) {
487 		IPSECLOG(LOG_DEBUG, "bad offset %u\n", *offp);
488 		IPSEC_ISTAT(proto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
489 			    IPCOMP_STAT_HDROPS);
490 		m_freem(*mp);
491 		return IPPROTO_DONE;
492 	} else if (*offp == sizeof(struct ip6_hdr)) {
493 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
494 	} else {
495 		/* Chase down the header chain... */
496 		protoff = sizeof(struct ip6_hdr);
497 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
498 
499 		do {
500 			protoff += l;
501 			m_copydata(*mp, protoff, sizeof(ip6e), &ip6e);
502 
503 			if (nxt == IPPROTO_AH)
504 				l = (ip6e.ip6e_len + 2) << 2;
505 			else
506 				l = (ip6e.ip6e_len + 1) << 3;
507 			KASSERT(l > 0);
508 
509 			nxt = ip6e.ip6e_nxt;
510 		} while (protoff + l < *offp);
511 
512 		/* Malformed packet check */
513 		if (protoff + l != *offp) {
514 			IPSECLOG(LOG_DEBUG, "bad packet header chain, "
515 			    "protoff %u, l %u, off %u\n", protoff, l, *offp);
516 			IPSEC_ISTAT(proto, ESP_STAT_HDROPS,
517 				    AH_STAT_HDROPS,
518 				    IPCOMP_STAT_HDROPS);
519 			m_freem(*mp);
520 			*mp = NULL;
521 			return IPPROTO_DONE;
522 		}
523 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
524 	}
525 	(void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
526 	return IPPROTO_DONE;
527 }
528 
529 extern	const struct ip6protosw inet6sw[];
530 extern	u_char ip6_protox[];
531 
532 /*
533  * IPsec input callback, called by the transform callback. Takes care of
534  * filtering and other sanity checks on the processed packet.
535  */
536 int
537 ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
538     int protoff)
539 {
540 	int af __diagused, sproto;
541 	struct ip6_hdr *ip6;
542 	struct secasindex *saidx;
543 	int nxt;
544 	u_int8_t prot, nxt8;
545 	int error, nest;
546 
547 	KASSERT(m != NULL);
548 	KASSERT(sav != NULL);
549 	saidx = &sav->sah->saidx;
550 	af = saidx->dst.sa.sa_family;
551 	KASSERTMSG(af == AF_INET6, "unexpected af %u", af);
552 	sproto = saidx->proto;
553 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
554 	    sproto == IPPROTO_IPCOMP,
555 	    "unexpected security protocol %u", sproto);
556 
557 	/* Sanity check */
558 	if (m == NULL) {
559 		IPSECLOG(LOG_DEBUG, "null mbuf");
560 		IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
561 		    IPCOMP_STAT_BADKCR);
562 		error = EINVAL;
563 		goto bad;
564 	}
565 
566 	/* Fix IPv6 header */
567 	if (m->m_len < sizeof(struct ip6_hdr) &&
568 	    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
569 
570 		char buf[IPSEC_ADDRSTRLEN];
571 		IPSECLOG(LOG_DEBUG, "processing failed for SA %s/%08lx\n",
572 		    ipsec_address(&sav->sah->saidx.dst,
573 		    buf, sizeof(buf)), (u_long) ntohl(sav->spi));
574 
575 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
576 		    IPCOMP_STAT_HDROPS);
577 		error = EACCES;
578 		goto bad;
579 	}
580 
581 	ip6 = mtod(m, struct ip6_hdr *);
582 	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
583 
584 	/* Save protocol */
585 	m_copydata(m, protoff, 1, &prot);
586 
587 #ifdef INET
588 	/* IP-in-IP encapsulation */
589 	if (prot == IPPROTO_IPIP) {
590 		struct ip ipn;
591 
592 		/* ipn will now contain the inner IPv4 header */
593 		m_copydata(m, skip, sizeof(struct ip), &ipn);
594 
595 #ifdef notyet
596 		/*
597 		 * Check that the inner source address is the same as
598 		 * the proxy address, if available.
599 		 */
600 		if ((saidx->proxy.sa.sa_family == AF_INET &&
601 		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
602 		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
603 		    (saidx->proxy.sa.sa_family != AF_INET &&
604 			saidx->proxy.sa.sa_family != 0)) {
605 
606 			char ipbuf[INET_ADDRSTRLEN];
607 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
608 			IPSECLOG(LOG_DEBUG,
609 			    "inner source address %s doesn't correspond to "
610 			    "expected proxy source %s, SA %s/%08lx\n",
611 			    IN_PRINT(ipbuf, ipn.ip_src),
612 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
613 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
614 			    (u_long) ntohl(sav->spi));
615 
616 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
617 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
618 			error = EACCES;
619 			goto bad;
620 		}
621 #endif /*XXX*/
622 	}
623 #endif /* INET */
624 
625 	/* IPv6-in-IP encapsulation */
626 	if (prot == IPPROTO_IPV6) {
627 		struct ip6_hdr ip6n;
628 
629 		/* ip6n will now contain the inner IPv6 header. */
630 		m_copydata(m, skip, sizeof(struct ip6_hdr), &ip6n);
631 
632 #ifdef notyet
633 		/*
634 		 * Check that the inner source address is the same as
635 		 * the proxy address, if available.
636 		 */
637 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
638 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
639 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
640 			&saidx->proxy.sin6.sin6_addr)) ||
641 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
642 			saidx->proxy.sa.sa_family != 0)) {
643 
644 			char ip6buf[INET6_ADDRSTRLEN];
645 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
646 			IPSECLOG(LOG_DEBUG,
647 			    "inner source address %s doesn't correspond to "
648 			    "expected proxy source %s, SA %s/%08lx\n",
649 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
650 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
651 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
652 			    (u_long) ntohl(sav->spi));
653 
654 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
655 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
656 			error = EACCES;
657 			goto bad;
658 		}
659 #endif /*XXX*/
660 	}
661 
662 	key_sa_recordxfer(sav, m);
663 
664 	/* Retrieve new protocol */
665 	m_copydata(m, protoff, sizeof(u_int8_t), &nxt8);
666 
667 	/*
668 	 * See the end of ip6_input for this logic.
669 	 * IPPROTO_IPV[46] case will be processed just like other ones
670 	 */
671 	nest = 0;
672 	nxt = nxt8;
673 	while (nxt != IPPROTO_DONE) {
674 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
675 			IP6_STATINC(IP6_STAT_TOOMANYHDR);
676 			error = EINVAL;
677 			goto bad;
678 		}
679 
680 		/*
681 		 * Protection against faulty packet - there should be
682 		 * more sanity checks in header chain processing.
683 		 */
684 		if (m->m_pkthdr.len < skip) {
685 			IP6_STATINC(IP6_STAT_TOOSHORT);
686 			in6_ifstat_inc(m_get_rcvif_NOMPSAFE(m),
687 				       ifs6_in_truncated);
688 			error = EINVAL;
689 			goto bad;
690 		}
691 		/*
692 		 * Enforce IPsec policy checking if we are seeing last header.
693 		 * note that we do not visit this with protocols with pcb layer
694 		 * code - like udp/tcp/raw ip.
695 		 */
696 		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
697 		    ipsec6_in_reject(m, NULL)) {
698 			error = EINVAL;
699 			goto bad;
700 		}
701 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
702 	}
703 	return 0;
704 bad:
705 	if (m)
706 		m_freem(m);
707 	return error;
708 }
709 #endif /* INET6 */
710