xref: /openbsd/sys/netinet/ipsec_input.c (revision db3296cf)
1 /*	$OpenBSD: ipsec_input.c,v 1.69 2003/07/28 10:10:16 markus Exp $	*/
2 /*
3  * The authors of this code are John Ioannidis (ji@tla.org),
4  * Angelos D. Keromytis (kermit@csd.uch.gr) and
5  * Niels Provos (provos@physnet.uni-hamburg.de).
6  *
7  * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
8  * in November 1995.
9  *
10  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11  * by Angelos D. Keromytis.
12  *
13  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14  * and Niels Provos.
15  *
16  * Additional features in 1999 by Angelos D. Keromytis.
17  *
18  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19  * Angelos D. Keromytis and Niels Provos.
20  * Copyright (c) 2001, Angelos D. Keromytis.
21  *
22  * Permission to use, copy, and modify this software with or without fee
23  * is hereby granted, provided that this entire notice is included in
24  * all copies of any software which is or includes a copy or
25  * modification of this software.
26  * You may use this code under the GNU public license if you so wish. Please
27  * contribute changes back to the authors under this freer than GPL license
28  * so that we may further the use of strong encryption without limitations to
29  * all.
30  *
31  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
32  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
33  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
34  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
35  * PURPOSE.
36  */
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/protosw.h>
41 #include <sys/mbuf.h>
42 #include <sys/socket.h>
43 #include <sys/sysctl.h>
44 #include <sys/kernel.h>
45 
46 #include <net/if.h>
47 #include <net/netisr.h>
48 #include <net/bpf.h>
49 
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/ip.h>
53 #include <netinet/ip_var.h>
54 #include <netinet/in_var.h>
55 #include <netinet/ip_icmp.h>
56 #include <netinet/tcp.h>
57 #include <netinet/udp.h>
58 
59 #ifdef INET6
60 #ifndef INET
61 #include <netinet/in.h>
62 #endif
63 #include <netinet/ip6.h>
64 #include <netinet6/ip6_var.h>
65 #include <netinet6/ip6protosw.h>
66 #endif /* INET6 */
67 
68 #include <netinet/ip_ipsp.h>
69 #include <netinet/ip_esp.h>
70 #include <netinet/ip_ah.h>
71 #include <netinet/ip_ipcomp.h>
72 
73 #include <net/if_enc.h>
74 
75 #include "bpfilter.h"
76 
77 int ipsec_common_input(struct mbuf *, int, int, int, int);
78 void *ipsec_common_ctlinput(int, struct sockaddr *, void *, int);
79 
80 #ifdef ENCDEBUG
81 #define DPRINTF(x)	if (encdebug) printf x
82 #else
83 #define DPRINTF(x)
84 #endif
85 
86 /* sysctl variables */
87 int esp_enable = 1;
88 int ah_enable = 1;
89 int ipcomp_enable = 0;
90 
91 #ifdef INET6
92 extern struct ip6protosw inet6sw[];
93 extern u_char ip6_protox[];
94 #endif
95 
96 /*
97  * ipsec_common_input() gets called when we receive an IPsec-protected packet
98  * in IPv4 or IPv6. All it does is find the right TDB and call the appropriate
99  * transform. The callback takes care of further processing (like ingress
100  * filtering).
101  */
102 int
103 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
104 {
105 #define IPSEC_ISTAT(x,y,z) (sproto == IPPROTO_ESP ? (x)++ : \
106 			    sproto == IPPROTO_AH ? (y)++ : (z)++)
107 
108 	union sockaddr_union dst_address;
109 	struct timeval tv;
110 	struct tdb *tdbp;
111 	u_int32_t spi;
112 	u_int16_t cpi;
113 	int s, error;
114 
115 	IPSEC_ISTAT(espstat.esps_input, ahstat.ahs_input,
116 	    ipcompstat.ipcomps_input);
117 
118 	if (m == 0) {
119 		DPRINTF(("ipsec_common_input(): NULL packet received\n"));
120 		IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
121 		    ipcompstat.ipcomps_hdrops);
122 		return EINVAL;
123 	}
124 
125 	if ((sproto == IPPROTO_ESP && !esp_enable) ||
126 	    (sproto == IPPROTO_AH && !ah_enable) ||
127 	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
128 		m_freem(m);
129 		IPSEC_ISTAT(espstat.esps_pdrops, ahstat.ahs_pdrops,
130 		    ipcompstat.ipcomps_pdrops);
131 		return EOPNOTSUPP;
132 	}
133 
134 	if (m->m_pkthdr.len - skip < 2 * sizeof(u_int32_t)) {
135 		m_freem(m);
136 		IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
137 		    ipcompstat.ipcomps_hdrops);
138 		DPRINTF(("ipsec_common_input(): packet too small\n"));
139 		return EINVAL;
140 	}
141 
142 	/* Retrieve the SPI from the relevant IPsec header */
143 	if (sproto == IPPROTO_ESP)
144 		m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
145 	else if (sproto == IPPROTO_AH)
146 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
147 		    (caddr_t) &spi);
148 	else if (sproto == IPPROTO_IPCOMP) {
149 		m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t),
150 		    (caddr_t) &cpi);
151 		spi = ntohl(htons(cpi));
152 	}
153 
154 	/*
155 	 * Find tunnel control block and (indirectly) call the appropriate
156 	 * kernel crypto routine. The resulting mbuf chain is a valid
157 	 * IP packet ready to go through input processing.
158 	 */
159 
160 	bzero(&dst_address, sizeof(dst_address));
161 	dst_address.sa.sa_family = af;
162 
163 	switch (af) {
164 #ifdef INET
165 	case AF_INET:
166 		dst_address.sin.sin_len = sizeof(struct sockaddr_in);
167 		m_copydata(m, offsetof(struct ip, ip_dst),
168 		    sizeof(struct in_addr),
169 		    (caddr_t) &(dst_address.sin.sin_addr));
170 		break;
171 #endif /* INET */
172 
173 #ifdef INET6
174 	case AF_INET6:
175 		dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
176 		m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
177 		    sizeof(struct in6_addr),
178 		    (caddr_t) &(dst_address.sin6.sin6_addr));
179 		break;
180 #endif /* INET6 */
181 
182 	default:
183 		DPRINTF(("ipsec_common_input(): unsupported protocol "
184 		    "family %d\n", af));
185 		m_freem(m);
186 		IPSEC_ISTAT(espstat.esps_nopf, ahstat.ahs_nopf,
187 		    ipcompstat.ipcomps_nopf);
188 		return EPFNOSUPPORT;
189 	}
190 
191 	s = spltdb();
192 	tdbp = gettdb(spi, &dst_address, sproto);
193 	if (tdbp == NULL) {
194 		splx(s);
195 		DPRINTF(("ipsec_common_input(): could not find SA for "
196 		    "packet to %s, spi %08x\n",
197 		    ipsp_address(dst_address), ntohl(spi)));
198 		m_freem(m);
199 		IPSEC_ISTAT(espstat.esps_notdb, ahstat.ahs_notdb,
200 		    ipcompstat.ipcomps_notdb);
201 		return ENOENT;
202 	}
203 
204 	if (tdbp->tdb_flags & TDBF_INVALID) {
205 		splx(s);
206 		DPRINTF(("ipsec_common_input(): attempted to use invalid SA %s/%08x/%u\n", ipsp_address(dst_address), ntohl(spi), tdbp->tdb_sproto));
207 		m_freem(m);
208 		IPSEC_ISTAT(espstat.esps_invalid, ahstat.ahs_invalid,
209 		    ipcompstat.ipcomps_invalid);
210 		return EINVAL;
211 	}
212 
213 	if (tdbp->tdb_xform == NULL) {
214 		splx(s);
215 		DPRINTF(("ipsec_common_input(): attempted to use uninitialized SA %s/%08x/%u\n", ipsp_address(dst_address), ntohl(spi), tdbp->tdb_sproto));
216 		m_freem(m);
217 		IPSEC_ISTAT(espstat.esps_noxform, ahstat.ahs_noxform,
218 		    ipcompstat.ipcomps_noxform);
219 		return ENXIO;
220 	}
221 
222 	if (tdbp->tdb_dst.sa.sa_family == AF_INET &&
223 	    sproto != IPPROTO_IPCOMP) {
224 		/*
225 		 * XXX The fragment conflicts with scoped nature of
226 		 * IPv6, so do it for only for IPv4 for now.
227 		 */
228 		m->m_pkthdr.rcvif = &encif[0].sc_if;
229 	}
230 
231 	/* Register first use, setup expiration timer. */
232 	if (tdbp->tdb_first_use == 0) {
233 		int pri;
234 
235 		pri = splhigh();
236 		tdbp->tdb_first_use = time.tv_sec;
237 		splx(pri);
238 
239 		tv.tv_usec = 0;
240 
241 		tv.tv_sec = tdbp->tdb_exp_first_use + tdbp->tdb_first_use;
242 		if (tdbp->tdb_flags & TDBF_FIRSTUSE)
243 			timeout_add(&tdbp->tdb_first_tmo, hzto(&tv));
244 
245 		tv.tv_sec = tdbp->tdb_first_use + tdbp->tdb_soft_first_use;
246 		if (tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE)
247 			timeout_add(&tdbp->tdb_sfirst_tmo, hzto(&tv));
248 	}
249 
250 	/*
251 	 * Call appropriate transform and return -- callback takes care of
252 	 * everything else.
253 	 */
254 	error = (*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff);
255 	splx(s);
256 	return error;
257 }
258 
259 /*
260  * IPsec input callback, called by the transform callback. Takes care of
261  * filtering and other sanity checks on the processed packet.
262  */
263 int
264 ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
265     struct m_tag *mt)
266 {
267 	int prot, af, sproto;
268 
269 #if NBPFILTER > 0
270 	struct ifnet *bpfif;
271 #endif
272 
273 #ifdef INET
274 	struct ip *ip, ipn;
275 #endif /* INET */
276 
277 #ifdef INET6
278 	struct ip6_hdr *ip6, ip6n;
279 #endif /* INET6 */
280 	struct m_tag *mtag;
281 	struct tdb_ident *tdbi;
282 
283 	af = tdbp->tdb_dst.sa.sa_family;
284 	sproto = tdbp->tdb_sproto;
285 
286 	tdbp->tdb_last_used = time.tv_sec;
287 
288 	/* Sanity check */
289 	if (m == NULL) {
290 		/* The called routine will print a message if necessary */
291 		IPSEC_ISTAT(espstat.esps_badkcr, ahstat.ahs_badkcr,
292 		    ipcompstat.ipcomps_badkcr);
293 		return EINVAL;
294 	}
295 
296 #ifdef INET
297 	/* Fix IPv4 header */
298 	if (tdbp->tdb_dst.sa.sa_family == AF_INET) {
299 		if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) {
300 			DPRINTF(("ipsec_common_input_cb(): processing failed "
301 			    "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst),
302 			    ntohl(tdbp->tdb_spi)));
303 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
304 			    ipcompstat.ipcomps_hdrops);
305 			return ENOBUFS;
306 		}
307 
308 		ip = mtod(m, struct ip *);
309 		ip->ip_len = htons(m->m_pkthdr.len);
310 		ip->ip_sum = 0;
311 		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
312 		prot = ip->ip_p;
313 
314 		/* IP-in-IP encapsulation */
315 		if (prot == IPPROTO_IPIP) {
316 			if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
317 				m_freem(m);
318 				IPSEC_ISTAT(espstat.esps_hdrops,
319 				    ahstat.ahs_hdrops,
320 				    ipcompstat.ipcomps_hdrops);
321 				return EINVAL;
322 			}
323 			/* ipn will now contain the inner IPv4 header */
324 			m_copydata(m, skip, sizeof(struct ip),
325 			    (caddr_t) &ipn);
326 
327 			/*
328 			 * Check that the inner source address is the same as
329 			 * the proxy address, if available.
330 			 */
331 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET &&
332 			    tdbp->tdb_proxy.sin.sin_addr.s_addr !=
333 			    INADDR_ANY &&
334 			    ipn.ip_src.s_addr !=
335 			    tdbp->tdb_proxy.sin.sin_addr.s_addr) ||
336 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET &&
337 				tdbp->tdb_proxy.sa.sa_family != 0)) {
338 
339 				DPRINTF(("ipsec_common_input_cb(): inner "
340 				    "source address %s doesn't correspond to "
341 				    "expected proxy source %s, SA %s/%08x\n",
342 				    inet_ntoa4(ipn.ip_src),
343 				    ipsp_address(tdbp->tdb_proxy),
344 				    ipsp_address(tdbp->tdb_dst),
345 				    ntohl(tdbp->tdb_spi)));
346 
347 				m_freem(m);
348 				IPSEC_ISTAT(espstat.esps_pdrops,
349 				    ahstat.ahs_pdrops,
350 				    ipcompstat.ipcomps_pdrops);
351 				return EACCES;
352 			}
353 		}
354 
355 #if INET6
356 		/* IPv6-in-IP encapsulation. */
357 		if (prot == IPPROTO_IPV6) {
358 			if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
359 				m_freem(m);
360 				IPSEC_ISTAT(espstat.esps_hdrops,
361 				    ahstat.ahs_hdrops,
362 				    ipcompstat.ipcomps_hdrops);
363 				return EINVAL;
364 			}
365 			/* ip6n will now contain the inner IPv6 header. */
366 			m_copydata(m, skip, sizeof(struct ip6_hdr),
367 			    (caddr_t) &ip6n);
368 
369 			/*
370 			 * Check that the inner source address is the same as
371 			 * the proxy address, if available.
372 			 */
373 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 &&
374 			    !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) &&
375 			    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
376 				&tdbp->tdb_proxy.sin6.sin6_addr)) ||
377 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET6 &&
378 				tdbp->tdb_proxy.sa.sa_family != 0)) {
379 
380 				DPRINTF(("ipsec_common_input_cb(): inner "
381 				    "source address %s doesn't correspond to "
382 				    "expected proxy source %s, SA %s/%08x\n",
383 				    ip6_sprintf(&ip6n.ip6_src),
384 				    ipsp_address(tdbp->tdb_proxy),
385 				    ipsp_address(tdbp->tdb_dst),
386 				    ntohl(tdbp->tdb_spi)));
387 
388 				m_freem(m);
389 				IPSEC_ISTAT(espstat.esps_pdrops,
390 				    ahstat.ahs_pdrops,
391 				    ipcompstat.ipcomps_pdrops);
392 				return EACCES;
393 			}
394 		}
395 #endif /* INET6 */
396 	}
397 #endif /* INET */
398 
399 #ifdef INET6
400 	/* Fix IPv6 header */
401 	if (af == INET6)
402 	{
403 		if (m->m_len < sizeof(struct ip6_hdr) &&
404 		    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
405 
406 			DPRINTF(("ipsec_common_input_cb(): processing failed "
407 			    "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst),
408 			    ntohl(tdbp->tdb_spi)));
409 
410 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
411 			    ipcompstat.ipcomps_hdrops);
412 			return EACCES;
413 		}
414 
415 		ip6 = mtod(m, struct ip6_hdr *);
416 		ip6->ip6_plen = htons(m->m_pkthdr.len -
417 		    sizeof(struct ip6_hdr));
418 
419 		/* Save protocol */
420 		m_copydata(m, protoff, 1, (unsigned char *) &prot);
421 
422 #ifdef INET
423 		/* IP-in-IP encapsulation */
424 		if (prot == IPPROTO_IPIP) {
425 			if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
426 				m_freem(m);
427 				IPSEC_ISTAT(espstat.esps_hdrops,
428 				    ahstat.ahs_hdrops,
429 				    ipcompstat.ipcomps_hdrops);
430 				return EINVAL;
431 			}
432 			/* ipn will now contain the inner IPv4 header */
433 			m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
434 
435 			/*
436 			 * Check that the inner source address is the same as
437 			 * the proxy address, if available.
438 			 */
439 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET &&
440 			    tdbp->tdb_proxy.sin.sin_addr.s_addr !=
441 			    INADDR_ANY &&
442 			    ipn.ip_src.s_addr !=
443 				tdbp->tdb_proxy.sin.sin_addr.s_addr) ||
444 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET &&
445 				tdbp->tdb_proxy.sa.sa_family != 0)) {
446 
447 				DPRINTF(("ipsec_common_input_cb(): inner "
448 				    "source address %s doesn't correspond to "
449 				    "expected proxy source %s, SA %s/%08x\n",
450 				    inet_ntoa4(ipn.ip_src),
451 				    ipsp_address(tdbp->tdb_proxy),
452 				    ipsp_address(tdbp->tdb_dst),
453 				    ntohl(tdbp->tdb_spi)));
454 
455 				m_freem(m);
456 				IPSEC_ISTAT(espstat.esps_pdrops,
457 				    ahstat.ahs_pdrops,
458 				    ipcompstat.ipcomps_pdrops);
459 				return EACCES;
460 			}
461 		}
462 #endif /* INET */
463 
464 		/* IPv6-in-IP encapsulation */
465 		if (prot == IPPROTO_IPV6) {
466 			if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
467 				m_freem(m);
468 				IPSEC_ISTAT(espstat.esps_hdrops,
469 				    ahstat.ahs_hdrops,
470 				    ipcompstat.ipcomps_hdrops);
471 				return EINVAL;
472 			}
473 			/* ip6n will now contain the inner IPv6 header. */
474 			m_copydata(m, skip, sizeof(struct ip6_hdr),
475 			    (caddr_t) &ip6n);
476 
477 			/*
478 			 * Check that the inner source address is the same as
479 			 * the proxy address, if available.
480 			 */
481 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 &&
482 			    !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) &&
483 			    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
484 				&tdbp->tdb_proxy.sin6.sin6_addr)) ||
485 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET6 &&
486 				tdbp->tdb_proxy.sa.sa_family != 0)) {
487 
488 				DPRINTF(("ipsec_common_input_cb(): inner "
489 				    "source address %s doesn't correspond to "
490 				    "expected proxy source %s, SA %s/%08x\n",
491 				    ip6_sprintf(&ip6n.ip6_src),
492 				    ipsp_address(tdbp->tdb_proxy),
493 				    ipsp_address(tdbp->tdb_dst),
494 				    ntohl(tdbp->tdb_spi)));
495 
496 				m_freem(m);
497 				IPSEC_ISTAT(espstat.esps_pdrops,
498 				    ahstat.ahs_pdrops,
499 				    ipcompstat.ipcomps_pdrops);
500 				return EACCES;
501 			}
502 		}
503 	}
504 #endif /* INET6 */
505 
506 	/*
507 	 * Record what we've done to the packet (under what SA it was
508 	 * processed). If we've been passed an mtag, it means the packet
509 	 * was already processed by an ethernet/crypto combo card and
510 	 * thus has a tag attached with all the right information, but
511 	 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
512 	 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
513 	 */
514 	if (mt == NULL && tdbp->tdb_sproto != IPPROTO_IPCOMP) {
515 		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
516 		    sizeof(struct tdb_ident), M_NOWAIT);
517 		if (mtag == NULL) {
518 			m_freem(m);
519 			DPRINTF(("ipsec_common_input_cb(): failed to "
520 			    "get tag\n"));
521 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
522 			    ipcompstat.ipcomps_hdrops);
523 			return ENOMEM;
524 		}
525 
526 		tdbi = (struct tdb_ident *)(mtag + 1);
527 		bcopy(&tdbp->tdb_dst, &tdbi->dst,
528 		    sizeof(union sockaddr_union));
529 		tdbi->proto = tdbp->tdb_sproto;
530 		tdbi->spi = tdbp->tdb_spi;
531 
532 		m_tag_prepend(m, mtag);
533 	} else {
534 		if (mt != NULL)
535 			mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
536 	}
537 
538 	if (sproto == IPPROTO_ESP) {
539 		/* Packet is confidential ? */
540 		if (tdbp->tdb_encalgxform)
541 			m->m_flags |= M_CONF;
542 
543 		/* Check if we had authenticated ESP. */
544 		if (tdbp->tdb_authalgxform)
545 			m->m_flags |= M_AUTH;
546 	} else if (sproto == IPPROTO_IPCOMP)
547 		m->m_flags |= M_COMP;
548 	else
549 		m->m_flags |= M_AUTH | M_AUTH_AH;
550 
551 	if (tdbp->tdb_flags & TDBF_TUNNELING)
552 		m->m_flags |= M_TUNNEL;
553 
554 #if NBPFILTER > 0
555 	bpfif = &encif[0].sc_if;
556 	if (bpfif->if_bpf) {
557 		/*
558 		 * We need to prepend the address family as
559 		 * a four byte field.  Cons up a dummy header
560 		 * to pacify bpf.  This is safe because bpf
561 		 * will only read from the mbuf (i.e., it won't
562 		 * try to free it or keep a pointer a to it).
563 		 */
564 		struct mbuf m1;
565 		struct enchdr hdr;
566 
567 		hdr.af = af;
568 		hdr.spi = tdbp->tdb_spi;
569 		hdr.flags = m->m_flags & (M_AUTH|M_CONF|M_AUTH_AH);
570 
571 		m1.m_flags = 0;
572 		m1.m_next = m;
573 		m1.m_len = ENC_HDRLEN;
574 		m1.m_data = (char *) &hdr;
575 
576 		bpf_mtap(bpfif->if_bpf, &m1);
577 	}
578 #endif
579 
580 	/* Call the appropriate IPsec transform callback. */
581 	switch (af) {
582 #ifdef INET
583 	case AF_INET:
584 		switch (sproto)
585 		{
586 		case IPPROTO_ESP:
587 			return esp4_input_cb(m);
588 
589 		case IPPROTO_AH:
590 			return ah4_input_cb(m);
591 
592 		case IPPROTO_IPCOMP:
593 			return ipcomp4_input_cb(m);
594 
595 		default:
596 			DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
597 			    " security protocol %d\n", sproto));
598 			m_freem(m);
599 			return EPFNOSUPPORT;
600 		}
601 		break;
602 #endif /* INET */
603 
604 #ifdef INET6
605 	case AF_INET6:
606 		switch (sproto) {
607 		case IPPROTO_ESP:
608 			return esp6_input_cb(m, skip, protoff);
609 
610 		case IPPROTO_AH:
611 			return ah6_input_cb(m, skip, protoff);
612 
613 		case IPPROTO_IPCOMP:
614 			return ipcomp6_input_cb(m, skip, protoff);
615 
616 		default:
617 			DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
618 			    " security protocol %d\n", sproto));
619 			m_freem(m);
620 			return EPFNOSUPPORT;
621 		}
622 		break;
623 #endif /* INET6 */
624 
625 	default:
626 		DPRINTF(("ipsec_common_input_cb(): unknown/unsupported "
627 		    "protocol family %d\n", af));
628 		m_freem(m);
629 		return EPFNOSUPPORT;
630 	}
631 #undef IPSEC_ISTAT
632 }
633 
634 int
635 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp,
636     size_t newlen)
637 {
638 	/* All sysctl names at this level are terminal. */
639 	if (namelen != 1)
640 		return ENOTDIR;
641 
642 	switch (name[0]) {
643 	case ESPCTL_ENABLE:
644 		return sysctl_int(oldp, oldlen, newp, newlen, &esp_enable);
645 	default:
646 		return ENOPROTOOPT;
647 	}
648 	/* NOTREACHED */
649 }
650 
651 int
652 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp,
653     size_t newlen)
654 {
655 	/* All sysctl names at this level are terminal. */
656 	if (namelen != 1)
657 		return ENOTDIR;
658 
659 	switch (name[0]) {
660 	case AHCTL_ENABLE:
661 		return sysctl_int(oldp, oldlen, newp, newlen, &ah_enable);
662 	default:
663 		return ENOPROTOOPT;
664     }
665     /* NOTREACHED */
666 }
667 
668 int
669 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp,
670     size_t newlen)
671 {
672 	/* All sysctl names at this level are terminal. */
673 	if (namelen != 1)
674 		return ENOTDIR;
675 
676 	switch (name[0]) {
677 	case IPCOMPCTL_ENABLE:
678 		return sysctl_int(oldp, oldlen, newp, newlen, &ipcomp_enable);
679 	default:
680 		return ENOPROTOOPT;
681 	}
682 	/* NOTREACHED */
683 }
684 
685 #ifdef INET
686 /* IPv4 AH wrapper. */
687 void
688 ah4_input(struct mbuf *m, ...)
689 {
690 	int skip;
691 
692 	va_list ap;
693 	va_start(ap, m);
694 	skip = va_arg(ap, int);
695 	va_end(ap);
696 
697 	ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
698 	    IPPROTO_AH);
699 	return;
700 }
701 
702 /* IPv4 AH callback. */
703 int
704 ah4_input_cb(struct mbuf *m, ...)
705 {
706 	struct ifqueue *ifq = &ipintrq;
707 	int s = splimp();
708 
709 	/*
710 	 * Interface pointer is already in first mbuf; chop off the
711 	 * `outer' header and reschedule.
712 	 */
713 
714 	if (IF_QFULL(ifq)) {
715 		IF_DROP(ifq);
716 		ahstat.ahs_qfull++;
717 		splx(s);
718 
719 		m_freem(m);
720 		DPRINTF(("ah4_input_cb(): dropped packet because of full "
721 		    "IP queue\n"));
722 		return ENOBUFS;
723 	}
724 
725 	IF_ENQUEUE(ifq, m);
726 	schednetisr(NETISR_IP);
727 	splx(s);
728 	return 0;
729 }
730 
731 
732 void *
733 ah4_ctlinput(int cmd, struct sockaddr *sa, void *v)
734 {
735 	if (sa->sa_family != AF_INET ||
736 	    sa->sa_len != sizeof(struct sockaddr_in))
737 		return (NULL);
738 
739 	return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_AH));
740 }
741 
742 /* IPv4 ESP wrapper. */
743 void
744 esp4_input(struct mbuf *m, ...)
745 {
746 	int skip;
747 
748 	va_list ap;
749 	va_start(ap, m);
750 	skip = va_arg(ap, int);
751 	va_end(ap);
752 
753 	ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
754 	    IPPROTO_ESP);
755 }
756 
757 /* IPv4 ESP callback. */
758 int
759 esp4_input_cb(struct mbuf *m, ...)
760 {
761 	struct ifqueue *ifq = &ipintrq;
762 	int s = splimp();
763 
764 	/*
765 	 * Interface pointer is already in first mbuf; chop off the
766 	 * `outer' header and reschedule.
767 	 */
768 	if (IF_QFULL(ifq)) {
769 		IF_DROP(ifq);
770 		espstat.esps_qfull++;
771 		splx(s);
772 
773 		m_freem(m);
774 		DPRINTF(("esp4_input_cb(): dropped packet because of full "
775 		    "IP queue\n"));
776 		return ENOBUFS;
777 	}
778 
779 	IF_ENQUEUE(ifq, m);
780 	schednetisr(NETISR_IP);
781 	splx(s);
782 	return 0;
783 }
784 
785 /* IPv4 IPCOMP wrapper */
786 void
787 ipcomp4_input(struct mbuf *m, ...)
788 {
789 	int skip;
790 	va_list ap;
791 	va_start(ap, m);
792 	skip = va_arg(ap, int);
793 	va_end(ap);
794 
795 	ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
796 	    IPPROTO_IPCOMP);
797 }
798 
799 /* IPv4 IPCOMP callback */
800 int
801 ipcomp4_input_cb(struct mbuf *m, ...)
802 {
803 	struct ifqueue *ifq = &ipintrq;
804 	int s = splimp();
805 
806 	/*
807 	 * Interface pointer is already in first mbuf; chop off the
808 	 * `outer' header and reschedule.
809 	 */
810 	if (IF_QFULL(ifq)) {
811 		IF_DROP(ifq);
812 		ipcompstat.ipcomps_qfull++;
813 		splx(s);
814 
815 		m_freem(m);
816 		DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n"));
817 		return ENOBUFS;
818 	}
819 
820 	IF_ENQUEUE(ifq, m);
821 	schednetisr(NETISR_IP);
822 	splx(s);
823 
824 	return 0;
825 }
826 
827 void *
828 ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
829 {
830 	extern u_int ip_mtudisc_timeout;
831 	struct ip *ip = v;
832 	int s;
833 
834 	if (cmd == PRC_MSGSIZE && ip && ip_mtudisc && ip->ip_v == 4) {
835 		struct tdb *tdbp;
836 		struct sockaddr_in dst;
837 		struct icmp *icp;
838 		int hlen = ip->ip_hl << 2;
839 		u_int32_t spi, mtu;
840 		ssize_t adjust;
841 
842 		/* Find the right MTU. */
843 		icp = (struct icmp *)((caddr_t) ip -
844 		    offsetof(struct icmp, icmp_ip));
845 		mtu = ntohs(icp->icmp_nextmtu);
846 
847 		/*
848 		 * Ignore the packet, if we do not receive a MTU
849 		 * or the MTU is too small to be acceptable.
850 		 */
851 		if (mtu < 296)
852 			return (NULL);
853 
854 		bzero(&dst, sizeof(struct sockaddr_in));
855 		dst.sin_family = AF_INET;
856 		dst.sin_len = sizeof(struct sockaddr_in);
857 		dst.sin_addr.s_addr = ip->ip_dst.s_addr;
858 
859 		bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t));
860 
861 		s = spltdb();
862 		tdbp = gettdb(spi, (union sockaddr_union *)&dst, proto);
863 		if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) {
864 			splx(s);
865 			return (NULL);
866 		}
867 
868 		/* Walk the chain backswards to the first tdb */
869 		for (; tdbp; tdbp = tdbp->tdb_inext) {
870 			if (tdbp->tdb_flags & TDBF_INVALID ||
871 			    (adjust = ipsec_hdrsz(tdbp)) == -1) {
872 				splx(s);
873 				return (NULL);
874 			}
875 
876 			mtu -= adjust;
877 
878 			/* Store adjusted MTU in tdb */
879 			tdbp->tdb_mtu = mtu;
880 			tdbp->tdb_mtutimeout = time.tv_sec +
881 			    ip_mtudisc_timeout;
882 		}
883 		splx(s);
884 		return (NULL);
885 	}
886 	return (NULL);
887 }
888 
889 void *
890 esp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
891 {
892 	if (sa->sa_family != AF_INET ||
893 	    sa->sa_len != sizeof(struct sockaddr_in))
894 		return (NULL);
895 
896 	return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_ESP));
897 }
898 #endif /* INET */
899 
900 #ifdef INET6
901 /* IPv6 AH wrapper. */
902 int
903 ah6_input(struct mbuf **mp, int *offp, int proto)
904 {
905 	int l = 0;
906 	int protoff;
907 	struct ip6_ext ip6e;
908 
909 	if (*offp < sizeof(struct ip6_hdr)) {
910 		DPRINTF(("ah6_input(): bad offset\n"));
911 		return IPPROTO_DONE;
912 	} else if (*offp == sizeof(struct ip6_hdr)) {
913 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
914 	} else {
915 		/* Chase down the header chain... */
916 		protoff = sizeof(struct ip6_hdr);
917 
918 		do {
919 			protoff += l;
920 			m_copydata(*mp, protoff, sizeof(ip6e),
921 			    (caddr_t) &ip6e);
922 
923 			if (ip6e.ip6e_nxt == IPPROTO_AH)
924 				l = (ip6e.ip6e_len + 2) << 2;
925 			else
926 				l = (ip6e.ip6e_len + 1) << 3;
927 #ifdef DIAGNOSTIC
928 			if (l <= 0)
929 				panic("ah6_input: l went zero or negative");
930 #endif
931 		} while (protoff + l < *offp);
932 
933 		/* Malformed packet check */
934 		if (protoff + l != *offp) {
935 			DPRINTF(("ah6_input(): bad packet header chain\n"));
936 			ahstat.ahs_hdrops++;
937 			m_freem(*mp);
938 			*mp = NULL;
939 			return IPPROTO_DONE;
940 		}
941 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
942 	}
943 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
944 	return IPPROTO_DONE;
945 }
946 
947 /* IPv6 AH callback. */
948 int
949 ah6_input_cb(struct mbuf *m, int off, int protoff)
950 {
951 	int nxt;
952 	u_int8_t nxt8;
953 	int nest = 0;
954 
955 	/* Retrieve new protocol */
956 	m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
957 	nxt = nxt8;
958 
959 	/*
960 	 * see the end of ip6_input for this logic.
961 	 * IPPROTO_IPV[46] case will be processed just like other ones
962 	 */
963 	while (nxt != IPPROTO_DONE) {
964 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
965 			ip6stat.ip6s_toomanyhdr++;
966 			goto bad;
967 		}
968 
969 		/*
970 		 * Protection against faulty packet - there should be
971 		 * more sanity checks in header chain processing.
972 		 */
973 		if (m->m_pkthdr.len < off) {
974 			ip6stat.ip6s_tooshort++;
975 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
976 			goto bad;
977 		}
978 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
979 	}
980 	return 0;
981 
982  bad:
983 	m_freem(m);
984 	return EINVAL;
985 }
986 
987 /* IPv6 ESP wrapper. */
988 int
989 esp6_input(struct mbuf **mp, int *offp, int proto)
990 {
991 	int l = 0;
992 	int protoff;
993 	struct ip6_ext ip6e;
994 
995 	if (*offp < sizeof(struct ip6_hdr)) {
996 		DPRINTF(("esp6_input(): bad offset\n"));
997 		return IPPROTO_DONE;
998 	} else if (*offp == sizeof(struct ip6_hdr)) {
999 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
1000 	} else {
1001 		/* Chase down the header chain... */
1002 		protoff = sizeof(struct ip6_hdr);
1003 
1004 		do {
1005 			protoff += l;
1006 			m_copydata(*mp, protoff, sizeof(ip6e),
1007 			    (caddr_t) &ip6e);
1008 
1009 			if (ip6e.ip6e_nxt == IPPROTO_AH)
1010 				l = (ip6e.ip6e_len + 2) << 2;
1011 			else
1012 				l = (ip6e.ip6e_len + 1) << 3;
1013 #ifdef DIAGNOSTIC
1014 			if (l <= 0)
1015 				panic("esp6_input: l went zero or negative");
1016 #endif
1017 		} while (protoff + l < *offp);
1018 
1019 		/* Malformed packet check */
1020 		if (protoff + l != *offp) {
1021 			DPRINTF(("esp6_input(): bad packet header chain\n"));
1022 			espstat.esps_hdrops++;
1023 			m_freem(*mp);
1024 			*mp = NULL;
1025 			return IPPROTO_DONE;
1026 		}
1027 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
1028 	}
1029 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
1030 	return IPPROTO_DONE;
1031 
1032 }
1033 
1034 /* IPv6 ESP callback */
1035 int
1036 esp6_input_cb(struct mbuf *m, int skip, int protoff)
1037 {
1038 	return ah6_input_cb(m, skip, protoff);
1039 }
1040 
1041 /* IPv6 IPcomp wrapper */
1042 int
1043 ipcomp6_input(struct mbuf **mp, int *offp, int proto)
1044 {
1045 	int l = 0;
1046 	int protoff;
1047 	struct ip6_ext ip6e;
1048 
1049 	if (*offp < sizeof(struct ip6_hdr)) {
1050 		DPRINTF(("ipcomp6_input(): bad offset\n"));
1051 		return IPPROTO_DONE;
1052 	} else if (*offp == sizeof(struct ip6_hdr)) {
1053 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
1054 	} else {
1055 		/* Chase down the header chain... */
1056 		protoff = sizeof(struct ip6_hdr);
1057 
1058 		do {
1059 			protoff += l;
1060 			m_copydata(*mp, protoff, sizeof(ip6e),
1061 			    (caddr_t) &ip6e);
1062 			if (ip6e.ip6e_nxt == IPPROTO_AH)
1063 				l = (ip6e.ip6e_len + 2) << 2;
1064 			else
1065 				l = (ip6e.ip6e_len + 1) << 3;
1066 #ifdef DIAGNOSTIC
1067 			if (l <= 0)
1068 				panic("ipcomp6_input: l went zero or negative");
1069 #endif
1070 		} while (protoff + l < *offp);
1071 
1072 		/* Malformed packet check */
1073 		if (protoff + l != *offp) {
1074 			DPRINTF(("ipcomp6_input(): bad packet header chain\n"));
1075 			ipcompstat.ipcomps_hdrops++;
1076 			m_freem(*mp);
1077 			*mp = NULL;
1078 			return IPPROTO_DONE;
1079 		}
1080 
1081 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
1082 	}
1083 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
1084 	return IPPROTO_DONE;
1085 }
1086 
1087 /* IPv6 IPcomp callback */
1088 int
1089 ipcomp6_input_cb(struct mbuf *m, int skip, int protoff)
1090 {
1091 	return ah6_input_cb(m, skip, protoff);
1092 }
1093 
1094 #endif /* INET6 */
1095