xref: /openbsd-src/sys/netinet/ipsec_input.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*	$OpenBSD: ipsec_input.c,v 1.54 2001/12/06 22:52:10 angelos 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 			    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;
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 	if ((*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff) == NULL) {
255 		splx(s);
256 		return EINVAL;
257 	} else {
258 		splx(s);
259 		return 0;
260 	}
261 }
262 
263 /*
264  * IPsec input callback, called by the transform callback. Takes care of
265  * filtering and other sanity checks on the processed packet.
266  */
267 int
268 ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
269     struct m_tag *mt)
270 {
271 	int prot, af, sproto;
272 
273 #if NBPFILTER > 0
274 	struct ifnet *bpfif;
275 #endif
276 
277 #ifdef INET
278 	struct ip *ip, ipn;
279 #endif /* INET */
280 
281 #ifdef INET6
282 	struct ip6_hdr *ip6, ip6n;
283 #endif /* INET6 */
284 	struct m_tag *mtag;
285 	struct tdb_ident *tdbi;
286 
287 	af = tdbp->tdb_dst.sa.sa_family;
288 	sproto = tdbp->tdb_sproto;
289 
290 	tdbp->tdb_last_used = time.tv_sec;
291 
292 	/* Sanity check */
293 	if (m == NULL) {
294 		/* The called routine will print a message if necessary */
295 		IPSEC_ISTAT(espstat.esps_badkcr, ahstat.ahs_badkcr,
296 		    ipcompstat.ipcomps_badkcr);
297 		return EINVAL;
298 	}
299 
300 #ifdef INET
301 	/* Fix IPv4 header */
302 	if (tdbp->tdb_dst.sa.sa_family == AF_INET) {
303 		if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) {
304 			DPRINTF(("ipsec_common_input_cb(): processing failed "
305 			    "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst),
306 			    ntohl(tdbp->tdb_spi)));
307 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
308 			    ipcompstat.ipcomps_hdrops);
309 			return ENOBUFS;
310 		}
311 
312 		ip = mtod(m, struct ip *);
313 		ip->ip_len = htons(m->m_pkthdr.len);
314 		HTONS(ip->ip_off);
315 		ip->ip_sum = 0;
316 		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
317 		prot = ip->ip_p;
318 
319 		/* IP-in-IP encapsulation */
320 		if (prot == IPPROTO_IPIP) {
321 			/* ipn will now contain the inner IPv4 header */
322 			m_copydata(m, ip->ip_hl << 2, sizeof(struct ip),
323 			    (caddr_t) &ipn);
324 
325 			/*
326 			 * Check that the inner source address is the same as
327 			 * the proxy address, if available.
328 			 */
329 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET &&
330 			    tdbp->tdb_proxy.sin.sin_addr.s_addr !=
331 			    INADDR_ANY &&
332 			    ipn.ip_src.s_addr !=
333 			    tdbp->tdb_proxy.sin.sin_addr.s_addr) ||
334 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET &&
335 				tdbp->tdb_proxy.sa.sa_family != 0)) {
336 
337 				DPRINTF(("ipsec_common_input_cb(): inner "
338 				    "source address %s doesn't correspond to "
339 				    "expected proxy source %s, SA %s/%08x\n",
340 				    inet_ntoa4(ipn.ip_src),
341 				    ipsp_address(tdbp->tdb_proxy),
342 				    ipsp_address(tdbp->tdb_dst),
343 				    ntohl(tdbp->tdb_spi)));
344 
345 				m_freem(m);
346 				IPSEC_ISTAT(espstat.esps_pdrops,
347 				    ahstat.ahs_pdrops,
348 				    ipcompstat.ipcomps_pdrops);
349 				return EACCES;
350 			}
351 		}
352 
353 #if INET6
354 		/* IPv6-in-IP encapsulation. */
355 		if (prot == IPPROTO_IPV6) {
356 			/* ip6n will now contain the inner IPv6 header. */
357 			m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr),
358 			    (caddr_t) &ip6n);
359 
360 			/*
361 			 * Check that the inner source address is the same as
362 			 * the proxy address, if available.
363 			 */
364 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 &&
365 			    !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) &&
366 			    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
367 				&tdbp->tdb_proxy.sin6.sin6_addr)) ||
368 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET6 &&
369 				tdbp->tdb_proxy.sa.sa_family != 0)) {
370 
371 				DPRINTF(("ipsec_common_input_cb(): inner "
372 				    "source address %s doesn't correspond to "
373 				    "expected proxy source %s, SA %s/%08x\n",
374 				    ip6_sprintf(&ip6n.ip6_src),
375 				    ipsp_address(tdbp->tdb_proxy),
376 				    ipsp_address(tdbp->tdb_dst),
377 				    ntohl(tdbp->tdb_spi)));
378 
379 				m_freem(m);
380 				IPSEC_ISTAT(espstat.esps_pdrops,
381 				    ahstat.ahs_pdrops,
382 				    ipcompstat.ipcomps_pdrops);
383 				return EACCES;
384 			}
385 		}
386 #endif /* INET6 */
387 	}
388 #endif /* INET */
389 
390 #ifdef INET6
391 	/* Fix IPv6 header */
392 	if (af == INET6)
393 	{
394 		if (m->m_len < sizeof(struct ip6_hdr) &&
395 		    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
396 
397 			DPRINTF(("ipsec_common_input_cb(): processing failed "
398 			    "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst),
399 			    ntohl(tdbp->tdb_spi)));
400 
401 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
402 			    ipcompstat.ipcomps_hdrops);
403 			return EACCES;
404 		}
405 
406 		ip6 = mtod(m, struct ip6_hdr *);
407 		ip6->ip6_plen = htons(m->m_pkthdr.len -
408 		    sizeof(struct ip6_hdr));
409 
410 		/* Save protocol */
411 		m_copydata(m, protoff, 1, (unsigned char *) &prot);
412 
413 #ifdef INET
414 		/* IP-in-IP encapsulation */
415 		if (prot == IPPROTO_IPIP) {
416 			/* ipn will now contain the inner IPv4 header */
417 			m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
418 
419 			/*
420 			 * Check that the inner source address is the same as
421 			 * the proxy address, if available.
422 			 */
423 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET &&
424 			    tdbp->tdb_proxy.sin.sin_addr.s_addr !=
425 			    INADDR_ANY &&
426 			    ipn.ip_src.s_addr !=
427 				tdbp->tdb_proxy.sin.sin_addr.s_addr) ||
428 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET &&
429 				tdbp->tdb_proxy.sa.sa_family != 0)) {
430 
431 				DPRINTF(("ipsec_common_input_cb(): inner "
432 				    "source address %s doesn't correspond to "
433 				    "expected proxy source %s, SA %s/%08x\n",
434 				    inet_ntoa4(ipn.ip_src),
435 				    ipsp_address(tdbp->tdb_proxy),
436 				    ipsp_address(tdbp->tdb_dst),
437 				    ntohl(tdbp->tdb_spi)));
438 
439 				m_freem(m);
440 				IPSEC_ISTAT(espstat.esps_pdrops,
441 				    ahstat.ahs_pdrops,
442 				    ipcompstat.ipcomps_pdrops);
443 				return EACCES;
444 			}
445 		}
446 #endif /* INET */
447 
448 		/* IPv6-in-IP encapsulation */
449 		if (prot == IPPROTO_IPV6) {
450 			/* ip6n will now contain the inner IPv6 header. */
451 			m_copydata(m, skip, sizeof(struct ip6_hdr),
452 			    (caddr_t) &ip6n);
453 
454 			/*
455 			 * Check that the inner source address is the same as
456 			 * the proxy address, if available.
457 			 */
458 			if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 &&
459 			    !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) &&
460 			    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
461 				&tdbp->tdb_proxy.sin6.sin6_addr)) ||
462 			    (tdbp->tdb_proxy.sa.sa_family != AF_INET6 &&
463 				tdbp->tdb_proxy.sa.sa_family != 0)) {
464 
465 				DPRINTF(("ipsec_common_input_cb(): inner "
466 				    "source address %s doesn't correspond to "
467 				    "expected proxy source %s, SA %s/%08x\n",
468 				    ip6_sprintf(&ip6n.ip6_src),
469 				    ipsp_address(tdbp->tdb_proxy),
470 				    ipsp_address(tdbp->tdb_dst),
471 				    ntohl(tdbp->tdb_spi)));
472 
473 				m_freem(m);
474 				IPSEC_ISTAT(espstat.esps_pdrops,
475 				    ahstat.ahs_pdrops,
476 				    ipcompstat.ipcomps_pdrops);
477 				return EACCES;
478 			}
479 		}
480 	}
481 #endif /* INET6 */
482 
483 	/*
484 	 * Record what we've done to the packet (under what SA it was
485 	 * processed). If we've been passed an mtag, it means the packet
486 	 * was already processed by an ethernet/crypto combo card and
487 	 * thus has a tag attached with all the right information, but
488 	 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
489 	 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
490 	 */
491 	if (mt == NULL && tdbp->tdb_sproto != IPPROTO_IPCOMP) {
492 		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
493 		    sizeof(struct tdb_ident), M_NOWAIT);
494 		if (mtag == NULL) {
495 			m_freem(m);
496 			DPRINTF(("ipsec_common_input_cb(): failed to "
497 			    "get tag\n"));
498 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
499 			    ipcompstat.ipcomps_hdrops);
500 			return ENOMEM;
501 		}
502 
503 		tdbi = (struct tdb_ident *)(mtag + 1);
504 		bcopy(&tdbp->tdb_dst, &tdbi->dst,
505 		    sizeof(union sockaddr_union));
506 		tdbi->proto = tdbp->tdb_sproto;
507 		tdbi->spi = tdbp->tdb_spi;
508 
509 		m_tag_prepend(m, mtag);
510 	}
511 	else
512 		mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
513 
514 	if (sproto == IPPROTO_ESP) {
515 		/* Packet is confidential ? */
516 		if (tdbp->tdb_encalgxform)
517 			m->m_flags |= M_CONF;
518 
519 		/* Check if we had authenticated ESP. */
520 		if (tdbp->tdb_authalgxform)
521 			m->m_flags |= M_AUTH;
522 	}
523 	else if (sproto == IPPROTO_IPCOMP)
524 		m->m_flags |= M_COMP;
525 	else
526 		m->m_flags |= M_AUTH;
527 
528 #if NBPFILTER > 0
529 	bpfif = &encif[0].sc_if;
530 	if (bpfif->if_bpf) {
531 		/*
532 		 * We need to prepend the address family as
533 		 * a four byte field.  Cons up a dummy header
534 		 * to pacify bpf.  This is safe because bpf
535 		 * will only read from the mbuf (i.e., it won't
536 		 * try to free it or keep a pointer a to it).
537 		 */
538 		struct mbuf m1;
539 		struct enchdr hdr;
540 
541 		hdr.af = af;
542 		hdr.spi = tdbp->tdb_spi;
543 		hdr.flags = m->m_flags & (M_AUTH|M_CONF);
544 
545 		m1.m_next = m;
546 		m1.m_len = ENC_HDRLEN;
547 		m1.m_data = (char *) &hdr;
548 
549 		bpf_mtap(bpfif->if_bpf, &m1);
550 	}
551 #endif
552 
553 	/* Call the appropriate IPsec transform callback. */
554 	switch (af) {
555 #ifdef INET
556 	case AF_INET:
557 		switch (sproto)
558 		{
559 		case IPPROTO_ESP:
560 			return esp4_input_cb(m);
561 
562 		case IPPROTO_AH:
563 			return ah4_input_cb(m);
564 
565 		case IPPROTO_IPCOMP:
566 			return ipcomp4_input_cb(m);
567 
568 		default:
569 			DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
570 			    " security protocol %d\n", sproto));
571 			m_freem(m);
572 			return EPFNOSUPPORT;
573 		}
574 		break;
575 #endif /* INET */
576 
577 #ifdef INET6
578 	case AF_INET6:
579 		switch (sproto) {
580 		case IPPROTO_ESP:
581 			return esp6_input_cb(m, skip, protoff);
582 
583 		case IPPROTO_AH:
584 			return ah6_input_cb(m, skip, protoff);
585 
586 		case IPPROTO_IPCOMP:
587 			return ipcomp6_input_cb(m, skip, protoff);
588 
589 		default:
590 			DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
591 			    " security protocol %d\n", sproto));
592 			m_freem(m);
593 			return EPFNOSUPPORT;
594 		}
595 		break;
596 #endif /* INET6 */
597 
598 	default:
599 		DPRINTF(("ipsec_common_input_cb(): unknown/unsupported "
600 		    "protocol family %d\n", af));
601 		m_freem(m);
602 		return EPFNOSUPPORT;
603 	}
604 #undef IPSEC_ISTAT
605 }
606 
607 int
608 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp,
609     size_t newlen)
610 {
611 	/* All sysctl names at this level are terminal. */
612 	if (namelen != 1)
613 		return ENOTDIR;
614 
615 	switch (name[0]) {
616 	case ESPCTL_ENABLE:
617 		return sysctl_int(oldp, oldlen, newp, newlen, &esp_enable);
618 	default:
619 		return ENOPROTOOPT;
620 	}
621 	/* NOTREACHED */
622 }
623 
624 int
625 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp,
626     size_t newlen)
627 {
628 	/* All sysctl names at this level are terminal. */
629 	if (namelen != 1)
630 		return ENOTDIR;
631 
632 	switch (name[0]) {
633 	case AHCTL_ENABLE:
634 		return sysctl_int(oldp, oldlen, newp, newlen, &ah_enable);
635 	default:
636 		return ENOPROTOOPT;
637     }
638     /* NOTREACHED */
639 }
640 
641 int
642 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp,
643     size_t newlen)
644 {
645 	/* All sysctl names at this level are terminal. */
646 	if (namelen != 1)
647 		return ENOTDIR;
648 
649 	switch (name[0]) {
650 	case IPCOMPCTL_ENABLE:
651 		return sysctl_int(oldp, oldlen, newp, newlen, &ipcomp_enable);
652 	default:
653 		return ENOPROTOOPT;
654 	}
655 	/* NOTREACHED */
656 }
657 
658 #ifdef INET
659 /* IPv4 AH wrapper. */
660 void
661 ah4_input(struct mbuf *m, ...)
662 {
663 	int skip;
664 
665 	va_list ap;
666 	va_start(ap, m);
667 	skip = va_arg(ap, int);
668 	va_end(ap);
669 
670 	ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
671 	    IPPROTO_AH);
672 	return;
673 }
674 
675 /* IPv4 AH callback. */
676 int
677 ah4_input_cb(struct mbuf *m, ...)
678 {
679 	struct ifqueue *ifq = &ipintrq;
680 	int s = splimp();
681 
682 	/*
683 	 * Interface pointer is already in first mbuf; chop off the
684 	 * `outer' header and reschedule.
685 	 */
686 
687 	if (IF_QFULL(ifq)) {
688 		IF_DROP(ifq);
689 		ahstat.ahs_qfull++;
690 		splx(s);
691 
692 		m_freem(m);
693 		DPRINTF(("ah4_input_cb(): dropped packet because of full "
694 		    "IP queue\n"));
695 		return ENOBUFS;
696 	}
697 
698 	IF_ENQUEUE(ifq, m);
699 	schednetisr(NETISR_IP);
700 	splx(s);
701 	return 0;
702 }
703 
704 
705 void *
706 ah4_ctlinput(int cmd, struct sockaddr *sa, void *v)
707 {
708 	if (sa->sa_family != AF_INET ||
709 	    sa->sa_len != sizeof(struct sockaddr_in))
710 		return (NULL);
711 
712 	return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_AH));
713 }
714 
715 /* IPv4 ESP wrapper. */
716 void
717 esp4_input(struct mbuf *m, ...)
718 {
719 	int skip;
720 
721 	va_list ap;
722 	va_start(ap, m);
723 	skip = va_arg(ap, int);
724 	va_end(ap);
725 
726 	ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
727 	    IPPROTO_ESP);
728 }
729 
730 /* IPv4 ESP callback. */
731 int
732 esp4_input_cb(struct mbuf *m, ...)
733 {
734 	struct ifqueue *ifq = &ipintrq;
735 	int s = splimp();
736 
737 	/*
738 	 * Interface pointer is already in first mbuf; chop off the
739 	 * `outer' header and reschedule.
740 	 */
741 	if (IF_QFULL(ifq)) {
742 		IF_DROP(ifq);
743 		espstat.esps_qfull++;
744 		splx(s);
745 
746 		m_freem(m);
747 		DPRINTF(("esp4_input_cb(): dropped packet because of full "
748 		    "IP queue\n"));
749 		return ENOBUFS;
750 	}
751 
752 	IF_ENQUEUE(ifq, m);
753 	schednetisr(NETISR_IP);
754 	splx(s);
755 	return 0;
756 }
757 
758 /* IPv4 IPCOMP wrapper */
759 void
760 ipcomp4_input(struct mbuf *m, ...)
761 {
762 	int skip;
763 	va_list ap;
764 	va_start(ap, m);
765 	skip = va_arg(ap, int);
766 	va_end(ap);
767 
768 	ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
769 	    IPPROTO_IPCOMP);
770 }
771 
772 /* IPv4 IPCOMP callback */
773 int
774 ipcomp4_input_cb(struct mbuf *m, ...)
775 {
776 	struct ifqueue *ifq = &ipintrq;
777 	int s = splimp();
778 
779 	/*
780 	 * Interface pointer is already in first mbuf; chop off the
781 	 * `outer' header and reschedule.
782 	 */
783 	if (IF_QFULL(ifq)) {
784 		IF_DROP(ifq);
785 		ipcompstat.ipcomps_qfull++;
786 		splx(s);
787 
788 		m_freem(m);
789 		DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n"));
790 		return ENOBUFS;
791 	}
792 
793 	IF_ENQUEUE(ifq, m);
794 	schednetisr(NETISR_IP);
795 	splx(s);
796 
797 	return 0;
798 }
799 
800 void *
801 ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
802 {
803 	extern u_int ip_mtudisc_timeout;
804 	struct ip *ip = v;
805 	int s;
806 
807 	if (cmd == PRC_MSGSIZE && ip && ip->ip_v == 4) {
808 		struct tdb *tdbp;
809 		struct sockaddr_in dst;
810 		struct icmp *icp;
811 		int hlen = ip->ip_hl << 2;
812 		u_int32_t spi, mtu;
813 		ssize_t adjust;
814 
815 		/* Find the right MTU. */
816 		icp = (struct icmp *)((caddr_t) ip -
817 		    offsetof(struct icmp, icmp_ip));
818 		mtu = ntohs(icp->icmp_nextmtu);
819 
820 		/*
821 		 * Ignore the packet, if we do not receive a MTU
822 		 * or the MTU is too small to be acceptable.
823 		 */
824 		if (mtu < 296)
825 			return (NULL);
826 
827 		bzero(&dst, sizeof(struct sockaddr_in));
828 		dst.sin_family = AF_INET;
829 		dst.sin_len = sizeof(struct sockaddr_in);
830 		dst.sin_addr.s_addr = ip->ip_dst.s_addr;
831 
832 		bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t));
833 
834 		s = spltdb();
835 		tdbp = gettdb(spi, (union sockaddr_union *)&dst, proto);
836 		if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) {
837 			splx(s);
838 			return (NULL);
839 		}
840 
841 		/* Walk the chain backswards to the first tdb */
842 		for (; tdbp; tdbp = tdbp->tdb_inext) {
843 			if (tdbp->tdb_flags & TDBF_INVALID ||
844 			    (adjust = ipsec_hdrsz(tdbp)) == -1) {
845 				splx(s);
846 				return (NULL);
847 			}
848 
849 			mtu -= adjust;
850 
851 			/* Store adjusted MTU in tdb */
852 			tdbp->tdb_mtu = mtu;
853 			tdbp->tdb_mtutimeout = time.tv_sec +
854 			    ip_mtudisc_timeout;
855 		}
856 		splx(s);
857 		return (NULL);
858 	}
859 	return (NULL);
860 }
861 
862 void *
863 esp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
864 {
865 	if (sa->sa_family != AF_INET ||
866 	    sa->sa_len != sizeof(struct sockaddr_in))
867 		return (NULL);
868 
869 	return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_ESP));
870 }
871 #endif /* INET */
872 
873 #ifdef INET6
874 /* IPv6 AH wrapper. */
875 int
876 ah6_input(struct mbuf **mp, int *offp, int proto)
877 {
878 	int l = 0;
879 	int protoff;
880 	struct ip6_ext ip6e;
881 
882 	if (*offp < sizeof(struct ip6_hdr)) {
883 		DPRINTF(("ah6_input(): bad offset\n"));
884 		return IPPROTO_DONE;
885 	} else if (*offp == sizeof(struct ip6_hdr)) {
886 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
887 	} else {
888 		/* Chase down the header chain... */
889 		protoff = sizeof(struct ip6_hdr);
890 
891 		do {
892 			protoff += l;
893 			m_copydata(*mp, protoff, sizeof(ip6e),
894 			    (caddr_t) &ip6e);
895 
896 			if (ip6e.ip6e_nxt == IPPROTO_AH)
897 				l = (ip6e.ip6e_len + 2) << 2;
898 			else
899 				l = (ip6e.ip6e_len + 1) << 3;
900 #ifdef DIAGNOSTIC
901 			if (l <= 0)
902 				panic("ah6_input: l went zero or negative");
903 #endif
904 		} while (protoff + l < *offp);
905 
906 		/* Malformed packet check */
907 		if (protoff + l != *offp) {
908 			DPRINTF(("ah6_input(): bad packet header chain\n"));
909 			ahstat.ahs_hdrops++;
910 			m_freem(*mp);
911 			*mp = NULL;
912 			return IPPROTO_DONE;
913 		}
914 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
915 	}
916 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
917 	return IPPROTO_DONE;
918 }
919 
920 /* IPv6 AH callback. */
921 int
922 ah6_input_cb(struct mbuf *m, int off, int protoff)
923 {
924 	int nxt;
925 	u_int8_t nxt8;
926 	int nest = 0;
927 
928 	/* Retrieve new protocol */
929 	m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
930 	nxt = nxt8;
931 
932 	/*
933 	 * see the end of ip6_input for this logic.
934 	 * IPPROTO_IPV[46] case will be processed just like other ones
935 	 */
936 	while (nxt != IPPROTO_DONE) {
937 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
938 			ip6stat.ip6s_toomanyhdr++;
939 			goto bad;
940 		}
941 
942 		/*
943 		 * Protection against faulty packet - there should be
944 		 * more sanity checks in header chain processing.
945 		 */
946 		if (m->m_pkthdr.len < off) {
947 			ip6stat.ip6s_tooshort++;
948 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
949 			goto bad;
950 		}
951 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
952 	}
953 	return 0;
954 
955  bad:
956 	m_freem(m);
957 	return EINVAL;
958 }
959 
960 /* IPv6 ESP wrapper. */
961 int
962 esp6_input(struct mbuf **mp, int *offp, int proto)
963 {
964 	int l = 0;
965 	int protoff;
966 	struct ip6_ext ip6e;
967 
968 	if (*offp < sizeof(struct ip6_hdr)) {
969 		DPRINTF(("esp6_input(): bad offset\n"));
970 		return IPPROTO_DONE;
971 	} else if (*offp == sizeof(struct ip6_hdr)) {
972 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
973 	} else {
974 		/* Chase down the header chain... */
975 		protoff = sizeof(struct ip6_hdr);
976 
977 		do {
978 			protoff += l;
979 			m_copydata(*mp, protoff, sizeof(ip6e),
980 			    (caddr_t) &ip6e);
981 
982 			if (ip6e.ip6e_nxt == IPPROTO_AH)
983 				l = (ip6e.ip6e_len + 2) << 2;
984 			else
985 				l = (ip6e.ip6e_len + 1) << 3;
986 #ifdef DIAGNOSTIC
987 			if (l <= 0)
988 				panic("esp6_input: l went zero or negative");
989 #endif
990 		} while (protoff + l < *offp);
991 
992 		/* Malformed packet check */
993 		if (protoff + l != *offp) {
994 			DPRINTF(("esp6_input(): bad packet header chain\n"));
995 			espstat.esps_hdrops++;
996 			m_freem(*mp);
997 			*mp = NULL;
998 			return IPPROTO_DONE;
999 		}
1000 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
1001 	}
1002 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
1003 	return IPPROTO_DONE;
1004 
1005 }
1006 
1007 /* IPv6 ESP callback */
1008 int
1009 esp6_input_cb(struct mbuf *m, int skip, int protoff)
1010 {
1011 	return ah6_input_cb(m, skip, protoff);
1012 }
1013 
1014 /* IPv6 IPcomp wrapper */
1015 int
1016 ipcomp6_input(struct mbuf **mp, int *offp, int proto)
1017 {
1018 	int l = 0;
1019 	int protoff;
1020 	struct ip6_ext ip6e;
1021 
1022 	if (*offp < sizeof(struct ip6_hdr)) {
1023 		DPRINTF(("ipcomp6_input(): bad offset\n"));
1024 		return IPPROTO_DONE;
1025 	} else if (*offp == sizeof(struct ip6_hdr)) {
1026 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
1027 	} else {
1028 		/* Chase down the header chain... */
1029 		protoff = sizeof(struct ip6_hdr);
1030 
1031 		do {
1032 			protoff += l;
1033 			m_copydata(*mp, protoff, sizeof(ip6e),
1034 			    (caddr_t) &ip6e);
1035 			if (ip6e.ip6e_nxt == IPPROTO_AH)
1036 				l = (ip6e.ip6e_len + 2) << 2;
1037 			else
1038 				l = (ip6e.ip6e_len + 1) << 3;
1039 #ifdef DIAGNOSTIC
1040 			if (l <= 0)
1041 				panic("ipcomp6_input: l went zero or negative");
1042 #endif
1043 		} while (protoff + l < *offp);
1044 
1045 		/* Malformed packet check */
1046 		if (protoff + l != *offp) {
1047 			DPRINTF(("ipcomp6_input(): bad packet header chain\n"));
1048 			ipcompstat.ipcomps_hdrops++;
1049 			m_freem(*mp);
1050 			*mp = NULL;
1051 			return IPPROTO_DONE;
1052 		}
1053 
1054 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
1055 	}
1056 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
1057 	return IPPROTO_DONE;
1058 }
1059 
1060 /* IPv6 IPcomp callback */
1061 int
1062 ipcomp6_input_cb(struct mbuf *m, int skip, int protoff)
1063 {
1064 	return ah6_input_cb(m, skip, protoff);
1065 }
1066 
1067 #endif /* INET6 */
1068 
1069 
1070 
1071