xref: /netbsd-src/sys/netipsec/ipsec_input.c (revision fc4f42693f9b1c31f39f9cf50af1bf2010325808)
1 /*	$NetBSD: ipsec_input.c,v 1.62 2018/02/26 09:04:29 maxv Exp $	*/
2 /*	$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.62 2018/02/26 09:04:29 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 #define	IPSEC_ISTAT(p, x, y, z)						\
102 do {									\
103 	switch (p) {							\
104 	case IPPROTO_ESP:						\
105 		ESP_STATINC(x);						\
106 		break;							\
107 	case IPPROTO_AH:						\
108 		AH_STATINC(y);						\
109 		break;							\
110 	default:							\
111 		IPCOMP_STATINC(z);					\
112 		break;							\
113 	}								\
114 } while (/*CONSTCOND*/0)
115 
116 /*
117  * fixup TCP/UDP checksum
118  *
119  * XXX: if we have NAT-OA payload from IKE server,
120  *      we must do the differential update of checksum.
121  *
122  * XXX: NAT-OAi/NAT-OAr drived from IKE initiator/responder.
123  *      how to know the IKE side from kernel?
124  */
125 static struct mbuf *
126 ipsec4_fixup_checksum(struct mbuf *m)
127 {
128 	struct ip *ip;
129 	struct tcphdr *th;
130 	struct udphdr *uh;
131 	int poff, off;
132 	int plen;
133 
134 	if (m->m_len < sizeof(*ip)) {
135 		m = m_pullup(m, sizeof(*ip));
136 		if (m == NULL)
137 			return NULL;
138 	}
139 	ip = mtod(m, struct ip *);
140 	poff = ip->ip_hl << 2;
141 	plen = ntohs(ip->ip_len) - poff;
142 
143 	switch (ip->ip_p) {
144 	case IPPROTO_TCP:
145 		IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
146 		if (th == NULL)
147 			return NULL;
148 		off = th->th_off << 2;
149 		if (off < sizeof(*th) || off > plen) {
150 			m_freem(m);
151 			return NULL;
152 		}
153 		th->th_sum = 0;
154 		th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
155 		break;
156 	case IPPROTO_UDP:
157 		IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
158 		if (uh == NULL)
159 			return NULL;
160 		off = sizeof(*uh);
161 		if (off > plen) {
162 			m_freem(m);
163 			return NULL;
164 		}
165 		uh->uh_sum = 0;
166 		uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
167 		break;
168 	default:
169 		/* no checksum */
170 		return m;
171 	}
172 
173 	return m;
174 }
175 
176 /*
177  * ipsec_common_input gets called when an IPsec-protected packet
178  * is received by IPv4 or IPv6.  It's job is to find the right SA
179  # and call the appropriate transform.  The transform callback
180  * takes care of further processing (like ingress filtering).
181  */
182 static int
183 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
184 {
185 	char buf[IPSEC_ADDRSTRLEN];
186 	union sockaddr_union dst_address;
187 	struct secasvar *sav;
188 	u_int32_t spi;
189 	u_int16_t sport;
190 	u_int16_t dport;
191 	int s, error;
192 
193 	IPSEC_ISTAT(sproto, ESP_STAT_INPUT, AH_STAT_INPUT,
194 		IPCOMP_STAT_INPUT);
195 
196 	KASSERT(m != NULL);
197 
198 	if ((sproto == IPPROTO_ESP && !esp_enable) ||
199 	    (sproto == IPPROTO_AH && !ah_enable) ||
200 	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
201 		m_freem(m);
202 		IPSEC_ISTAT(sproto, ESP_STAT_PDROPS, AH_STAT_PDROPS,
203 		    IPCOMP_STAT_PDROPS);
204 		return EOPNOTSUPP;
205 	}
206 
207 	if (m->m_pkthdr.len - skip < 2 * sizeof(u_int32_t)) {
208 		m_freem(m);
209 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
210 		    IPCOMP_STAT_HDROPS);
211 		IPSECLOG(LOG_DEBUG, "packet too small\n");
212 		return EINVAL;
213 	}
214 
215 	/* Retrieve the SPI from the relevant IPsec header */
216 	if (sproto == IPPROTO_ESP) {
217 		m_copydata(m, skip, sizeof(u_int32_t), &spi);
218 	} else if (sproto == IPPROTO_AH) {
219 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), &spi);
220 	} else if (sproto == IPPROTO_IPCOMP) {
221 		u_int16_t cpi;
222 		m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), &cpi);
223 		spi = ntohl(htons(cpi));
224 	} else {
225 		panic("%s called with bad protocol number: %d\n", __func__,
226 		    sproto);
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
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
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 	if (__predict_false(m == NULL)) {
333 		panic("%s: NULL mbuf", __func__);
334 	}
335 	if (__predict_false(skip < sizeof(struct ip))) {
336 		panic("%s: short skip", __func__);
337 	}
338 
339 	KASSERT(sav != NULL);
340 	saidx = &sav->sah->saidx;
341 	af = saidx->dst.sa.sa_family;
342 	KASSERTMSG(af == AF_INET, "unexpected af %u", af);
343 	sproto = saidx->proto;
344 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
345 	    sproto == IPPROTO_IPCOMP,
346 	    "unexpected security protocol %u", sproto);
347 
348 	/*
349 	 * Update the IPv4 header. The length of the packet may have changed,
350 	 * so fix it, and recompute the checksum.
351 	 */
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 	ip = mtod(m, struct ip *);
365 	ip->ip_len = htons(m->m_pkthdr.len);
366 	ip->ip_sum = 0;
367 	ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
368 
369 	/*
370 	 * Update TCP/UDP checksum
371 	 * XXX: should only do it in NAT-T case
372 	 * XXX: should do it incrementally, see FreeBSD code.
373 	 */
374 	m = ipsec4_fixup_checksum(m);
375 	if (m == NULL)
376 		goto cantpull;
377 	ip = mtod(m, struct ip *);
378 
379 	prot = ip->ip_p;
380 
381 #ifdef notyet
382 	/* IP-in-IP encapsulation */
383 	if (prot == IPPROTO_IPIP) {
384 		struct ip ipn;
385 
386 		/* ipn will now contain the inner IPv4 header */
387 		/* XXX: check m_pkthdr.len */
388 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), &ipn);
389 
390 		/* XXX PROXY address isn't recorded in SAH */
391 		/*
392 		 * Check that the inner source address is the same as
393 		 * the proxy address, if available.
394 		 */
395 		if ((saidx->proxy.sa.sa_family == AF_INET &&
396 		    saidx->proxy.sin.sin_addr.s_addr !=
397 		    INADDR_ANY &&
398 		    ipn.ip_src.s_addr !=
399 		    saidx->proxy.sin.sin_addr.s_addr) ||
400 		    (saidx->proxy.sa.sa_family != AF_INET &&
401 			saidx->proxy.sa.sa_family != 0)) {
402 
403 			char ipbuf[INET_ADDRSTRLEN];
404 			IPSECLOG(LOG_DEBUG,
405 			    "inner source address %s doesn't correspond to "
406 			    "expected proxy source %s, SA %s/%08lx\n",
407 			    IN_PRINT(ipbuf, ipn.ip_src),
408 			    ipsp_address(saidx->proxy),
409 			    ipsp_address(saidx->dst),
410 			    (u_long) ntohl(sav->spi));
411 
412 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
413 			    AH_STAT_PDROPS,
414 			    IPCOMP_STAT_PDROPS);
415 			error = EACCES;
416 			goto bad;
417 		}
418 	}
419 #if INET6
420 	/* IPv6-in-IP encapsulation. */
421 	if (prot == IPPROTO_IPV6) {
422 		struct ip6_hdr ip6n;
423 
424 		/* ip6n will now contain the inner IPv6 header. */
425 		/* XXX: check m_pkthdr.len */
426 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), &ip6n);
427 
428 		/*
429 		 * Check that the inner source address is the same as
430 		 * the proxy address, if available.
431 		 */
432 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
433 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
434 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
435 			&saidx->proxy.sin6.sin6_addr)) ||
436 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
437 			saidx->proxy.sa.sa_family != 0)) {
438 
439 			char ip6buf[INET6_ADDRSTRLEN];
440 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
441 			IPSECLOG(LOG_DEBUG,
442 			    "inner source address %s doesn't correspond to "
443 			    "expected proxy source %s, SA %s/%08lx\n",
444 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
445 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
446 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
447 			    (u_long) ntohl(sav->spi));
448 
449 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
450 			    AH_STAT_PDROPS,
451 			    IPCOMP_STAT_PDROPS);
452 			error = EACCES;
453 			goto bad;
454 		}
455 	}
456 #endif /* INET6 */
457 #endif /* notyet */
458 
459 	key_sa_recordxfer(sav, m);		/* record data transfer */
460 
461 	if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 &&
462 	    ipsec_in_reject(m, NULL)) {
463 		error = EINVAL;
464 		goto bad;
465 	}
466 	(*inetsw[ip_protox[prot]].pr_input)(m, skip, prot);
467 	return 0;
468 
469 bad:
470 	m_freem(m);
471 	return error;
472 }
473 #endif /* INET */
474 
475 #ifdef INET6
476 int
477 ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
478 {
479 	int l = 0;
480 	int protoff, nxt;
481 	struct ip6_ext ip6e;
482 
483 	if (*offp < sizeof(struct ip6_hdr)) {
484 		IPSECLOG(LOG_DEBUG, "bad offset %u\n", *offp);
485 		IPSEC_ISTAT(proto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
486 			    IPCOMP_STAT_HDROPS);
487 		m_freem(*mp);
488 		return IPPROTO_DONE;
489 	} else if (*offp == sizeof(struct ip6_hdr)) {
490 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
491 	} else {
492 		/* Chase down the header chain... */
493 		protoff = sizeof(struct ip6_hdr);
494 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
495 
496 		do {
497 			protoff += l;
498 			m_copydata(*mp, protoff, sizeof(ip6e), &ip6e);
499 
500 			if (nxt == IPPROTO_AH)
501 				l = (ip6e.ip6e_len + 2) << 2;
502 			else if (nxt == IPPROTO_FRAGMENT)
503 				l = sizeof(struct ip6_frag);
504 			else
505 				l = (ip6e.ip6e_len + 1) << 3;
506 			KASSERT(l > 0);
507 
508 			nxt = ip6e.ip6e_nxt;
509 		} while (protoff + l < *offp);
510 
511 		/* Malformed packet check */
512 		if (protoff + l != *offp) {
513 			IPSECLOG(LOG_DEBUG, "bad packet header chain, "
514 			    "protoff %u, l %u, off %u\n", protoff, l, *offp);
515 			IPSEC_ISTAT(proto, ESP_STAT_HDROPS,
516 				    AH_STAT_HDROPS,
517 				    IPCOMP_STAT_HDROPS);
518 			m_freem(*mp);
519 			*mp = NULL;
520 			return IPPROTO_DONE;
521 		}
522 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
523 	}
524 	(void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
525 	return IPPROTO_DONE;
526 }
527 
528 extern const struct ip6protosw inet6sw[];
529 extern u_char ip6_protox[];
530 
531 /*
532  * IPsec input callback, called by the transform callback. Takes care of
533  * filtering and other sanity checks on the processed packet.
534  */
535 int
536 ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
537     int protoff)
538 {
539 	int af __diagused, sproto;
540 	struct ip6_hdr *ip6;
541 	struct secasindex *saidx;
542 	int nxt;
543 	u_int8_t prot, nxt8;
544 	int error, nest;
545 
546 	if (__predict_false(m == NULL)) {
547 		panic("%s: NULL mbuf", __func__);
548 	}
549 
550 	KASSERT(sav != NULL);
551 	saidx = &sav->sah->saidx;
552 	af = saidx->dst.sa.sa_family;
553 	KASSERTMSG(af == AF_INET6, "unexpected af %u", af);
554 	sproto = saidx->proto;
555 	KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
556 	    sproto == IPPROTO_IPCOMP,
557 	    "unexpected security protocol %u", sproto);
558 
559 	/* Fix IPv6 header */
560 	if (m->m_len < sizeof(struct ip6_hdr) &&
561 	    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
562 		char buf[IPSEC_ADDRSTRLEN];
563 		IPSECLOG(LOG_DEBUG, "processing failed for SA %s/%08lx\n",
564 		    ipsec_address(&sav->sah->saidx.dst,
565 		    buf, sizeof(buf)), (u_long) ntohl(sav->spi));
566 		IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
567 		    IPCOMP_STAT_HDROPS);
568 		error = EACCES;
569 		goto bad;
570 	}
571 
572 	ip6 = mtod(m, struct ip6_hdr *);
573 	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
574 
575 	/* Save protocol */
576 	m_copydata(m, protoff, 1, &prot);
577 
578 #ifdef notyet
579 #ifdef INET
580 	/* IP-in-IP encapsulation */
581 	if (prot == IPPROTO_IPIP) {
582 		struct ip ipn;
583 
584 		/* ipn will now contain the inner IPv4 header */
585 		/* XXX: check m_pkthdr.len */
586 		m_copydata(m, skip, sizeof(struct ip), &ipn);
587 
588 		/*
589 		 * Check that the inner source address is the same as
590 		 * the proxy address, if available.
591 		 */
592 		if ((saidx->proxy.sa.sa_family == AF_INET &&
593 		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
594 		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
595 		    (saidx->proxy.sa.sa_family != AF_INET &&
596 			saidx->proxy.sa.sa_family != 0)) {
597 
598 			char ipbuf[INET_ADDRSTRLEN];
599 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
600 			IPSECLOG(LOG_DEBUG,
601 			    "inner source address %s doesn't correspond to "
602 			    "expected proxy source %s, SA %s/%08lx\n",
603 			    IN_PRINT(ipbuf, ipn.ip_src),
604 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
605 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
606 			    (u_long) ntohl(sav->spi));
607 
608 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
609 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
610 			error = EACCES;
611 			goto bad;
612 		}
613 	}
614 #endif /* INET */
615 	/* IPv6-in-IP encapsulation */
616 	if (prot == IPPROTO_IPV6) {
617 		struct ip6_hdr ip6n;
618 
619 		/* ip6n will now contain the inner IPv6 header. */
620 		/* XXX: check m_pkthdr.len */
621 		m_copydata(m, skip, sizeof(struct ip6_hdr), &ip6n);
622 
623 		/*
624 		 * Check that the inner source address is the same as
625 		 * the proxy address, if available.
626 		 */
627 		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
628 		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
629 		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
630 			&saidx->proxy.sin6.sin6_addr)) ||
631 		    (saidx->proxy.sa.sa_family != AF_INET6 &&
632 			saidx->proxy.sa.sa_family != 0)) {
633 
634 			char ip6buf[INET6_ADDRSTRLEN];
635 			char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
636 			IPSECLOG(LOG_DEBUG,
637 			    "inner source address %s doesn't correspond to "
638 			    "expected proxy source %s, SA %s/%08lx\n",
639 			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
640 			    ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
641 			    ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
642 			    (u_long) ntohl(sav->spi));
643 
644 			IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
645 			    AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
646 			error = EACCES;
647 			goto bad;
648 		}
649 	}
650 #endif /* notyet */
651 
652 	key_sa_recordxfer(sav, m);
653 
654 	/* Retrieve new protocol */
655 	m_copydata(m, protoff, sizeof(u_int8_t), &nxt8);
656 
657 	/*
658 	 * See the end of ip6_input for this logic.
659 	 * IPPROTO_IPV[46] case will be processed just like other ones
660 	 */
661 	nest = 0;
662 	nxt = nxt8;
663 	while (nxt != IPPROTO_DONE) {
664 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
665 			IP6_STATINC(IP6_STAT_TOOMANYHDR);
666 			error = EINVAL;
667 			goto bad;
668 		}
669 
670 		/*
671 		 * Protection against faulty packet - there should be
672 		 * more sanity checks in header chain processing.
673 		 */
674 		if (m->m_pkthdr.len < skip) {
675 			IP6_STATINC(IP6_STAT_TOOSHORT);
676 			in6_ifstat_inc(m_get_rcvif_NOMPSAFE(m),
677 			    ifs6_in_truncated);
678 			error = EINVAL;
679 			goto bad;
680 		}
681 
682 		/*
683 		 * Enforce IPsec policy checking if we are seeing last header.
684 		 * note that we do not visit this with protocols with pcb layer
685 		 * code - like udp/tcp/raw ip.
686 		 */
687 		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
688 		    ipsec_in_reject(m, NULL)) {
689 			error = EINVAL;
690 			goto bad;
691 		}
692 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
693 	}
694 	return 0;
695 
696 bad:
697 	if (m)
698 		m_freem(m);
699 	return error;
700 }
701 #endif /* INET6 */
702