xref: /openbsd-src/sys/netinet/ipsec_input.c (revision d59bb9942320b767f2a19aaa7690c8c6e30b724c)
1 /*	$OpenBSD: ipsec_input.c,v 1.145 2017/02/28 09:59:34 mpi 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 "pf.h"
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/protosw.h>
43 #include <sys/mbuf.h>
44 #include <sys/socket.h>
45 #include <sys/sysctl.h>
46 #include <sys/kernel.h>
47 #include <sys/timeout.h>
48 
49 #include <net/if.h>
50 #include <net/if_var.h>
51 #include <net/netisr.h>
52 #include <net/bpf.h>
53 #include <net/route.h>
54 
55 #include <netinet/in.h>
56 #include <netinet/ip.h>
57 #include <netinet/ip_var.h>
58 #include <netinet/ip_icmp.h>
59 #include <netinet/tcp.h>
60 #include <netinet/udp.h>
61 
62 #if NPF > 0
63 #include <net/pfvar.h>
64 #endif
65 
66 #ifdef INET6
67 #include <netinet6/in6_var.h>
68 #include <netinet/ip6.h>
69 #include <netinet6/ip6_var.h>
70 #include <netinet6/ip6protosw.h>
71 #endif /* INET6 */
72 
73 #include <netinet/ip_ipsp.h>
74 #include <netinet/ip_esp.h>
75 #include <netinet/ip_ah.h>
76 #include <netinet/ip_ipcomp.h>
77 
78 #include <net/if_enc.h>
79 
80 #include "bpfilter.h"
81 
82 void ipsec_common_ctlinput(u_int, int, struct sockaddr *, void *, int);
83 
84 #ifdef ENCDEBUG
85 #define DPRINTF(x)	if (encdebug) printf x
86 #else
87 #define DPRINTF(x)
88 #endif
89 
90 /* sysctl variables */
91 int esp_enable = 1;
92 int ah_enable = 1;
93 int ipcomp_enable = 0;
94 
95 int *espctl_vars[ESPCTL_MAXID] = ESPCTL_VARS;
96 int *ahctl_vars[AHCTL_MAXID] = AHCTL_VARS;
97 int *ipcompctl_vars[IPCOMPCTL_MAXID] = IPCOMPCTL_VARS;
98 
99 /*
100  * ipsec_common_input() gets called when we receive an IPsec-protected packet
101  * in IPv4 or IPv6. All it does is find the right TDB and call the appropriate
102  * transform. The callback takes care of further processing (like ingress
103  * filtering).
104  */
105 int
106 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto,
107     int udpencap)
108 {
109 #define IPSEC_ISTAT(x,y,z) (sproto == IPPROTO_ESP ? (x)++ : \
110 			    sproto == IPPROTO_AH ? (y)++ : (z)++)
111 
112 	union sockaddr_union dst_address;
113 	struct tdb *tdbp;
114 	struct ifnet *encif;
115 	u_int32_t spi;
116 	u_int16_t cpi;
117 	int error;
118 #ifdef ENCDEBUG
119 	char buf[INET6_ADDRSTRLEN];
120 #endif
121 
122 	splsoftassert(IPL_SOFTNET);
123 
124 	IPSEC_ISTAT(espstat.esps_input, ahstat.ahs_input,
125 	    ipcompstat.ipcomps_input);
126 
127 	if (m == NULL) {
128 		DPRINTF(("ipsec_common_input(): NULL packet received\n"));
129 		IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
130 		    ipcompstat.ipcomps_hdrops);
131 		return EINVAL;
132 	}
133 
134 	if ((sproto == IPPROTO_ESP && !esp_enable) ||
135 	    (sproto == IPPROTO_AH && !ah_enable) ||
136 #if NPF > 0
137 	    (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
138 #endif
139 	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
140 		switch (af) {
141 		case AF_INET:
142 			rip_input(&m, &skip, sproto);
143 			break;
144 #ifdef INET6
145 		case AF_INET6:
146 			rip6_input(&m, &skip, sproto);
147 			break;
148 #endif /* INET6 */
149 		default:
150 			DPRINTF(("ipsec_common_input(): unsupported protocol "
151 			    "family %d\n", af));
152 			m_freem(m);
153 			IPSEC_ISTAT(espstat.esps_nopf, ahstat.ahs_nopf,
154 			    ipcompstat.ipcomps_nopf);
155 			return EPFNOSUPPORT;
156 		}
157 		return 0;
158 	}
159 	if ((sproto == IPPROTO_IPCOMP) && (m->m_flags & M_COMP)) {
160 		m_freem(m);
161 		ipcompstat.ipcomps_pdrops++;
162 		DPRINTF(("ipsec_common_input(): repeated decompression\n"));
163 		return EINVAL;
164 	}
165 
166 	if (m->m_pkthdr.len - skip < 2 * sizeof(u_int32_t)) {
167 		m_freem(m);
168 		IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
169 		    ipcompstat.ipcomps_hdrops);
170 		DPRINTF(("ipsec_common_input(): packet too small\n"));
171 		return EINVAL;
172 	}
173 
174 	/* Retrieve the SPI from the relevant IPsec header */
175 	if (sproto == IPPROTO_ESP)
176 		m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
177 	else if (sproto == IPPROTO_AH)
178 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
179 		    (caddr_t) &spi);
180 	else if (sproto == IPPROTO_IPCOMP) {
181 		m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t),
182 		    (caddr_t) &cpi);
183 		spi = ntohl(htons(cpi));
184 	}
185 
186 	/*
187 	 * Find tunnel control block and (indirectly) call the appropriate
188 	 * kernel crypto routine. The resulting mbuf chain is a valid
189 	 * IP packet ready to go through input processing.
190 	 */
191 
192 	memset(&dst_address, 0, sizeof(dst_address));
193 	dst_address.sa.sa_family = af;
194 
195 	switch (af) {
196 	case AF_INET:
197 		dst_address.sin.sin_len = sizeof(struct sockaddr_in);
198 		m_copydata(m, offsetof(struct ip, ip_dst),
199 		    sizeof(struct in_addr),
200 		    (caddr_t) &(dst_address.sin.sin_addr));
201 		break;
202 
203 #ifdef INET6
204 	case AF_INET6:
205 		dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
206 		m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
207 		    sizeof(struct in6_addr),
208 		    (caddr_t) &(dst_address.sin6.sin6_addr));
209 		in6_recoverscope(&dst_address.sin6,
210 		    &dst_address.sin6.sin6_addr);
211 		break;
212 #endif /* INET6 */
213 
214 	default:
215 		DPRINTF(("ipsec_common_input(): unsupported protocol "
216 		    "family %d\n", af));
217 		m_freem(m);
218 		IPSEC_ISTAT(espstat.esps_nopf, ahstat.ahs_nopf,
219 		    ipcompstat.ipcomps_nopf);
220 		return EPFNOSUPPORT;
221 	}
222 
223 	tdbp = gettdb(rtable_l2(m->m_pkthdr.ph_rtableid),
224 	    spi, &dst_address, sproto);
225 	if (tdbp == NULL) {
226 		DPRINTF(("ipsec_common_input(): could not find SA for "
227 		    "packet to %s, spi %08x\n",
228 		    ipsp_address(&dst_address, buf, sizeof(buf)), ntohl(spi)));
229 		m_freem(m);
230 		IPSEC_ISTAT(espstat.esps_notdb, ahstat.ahs_notdb,
231 		    ipcompstat.ipcomps_notdb);
232 		return ENOENT;
233 	}
234 
235 	if (tdbp->tdb_flags & TDBF_INVALID) {
236 		DPRINTF(("ipsec_common_input(): attempted to use invalid "
237 		    "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf,
238 		    sizeof(buf)), ntohl(spi), tdbp->tdb_sproto));
239 		m_freem(m);
240 		IPSEC_ISTAT(espstat.esps_invalid, ahstat.ahs_invalid,
241 		    ipcompstat.ipcomps_invalid);
242 		return EINVAL;
243 	}
244 
245 	if (udpencap && !(tdbp->tdb_flags & TDBF_UDPENCAP)) {
246 		DPRINTF(("ipsec_common_input(): attempted to use non-udpencap "
247 		    "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf,
248 		    sizeof(buf)), ntohl(spi), tdbp->tdb_sproto));
249 		m_freem(m);
250 		espstat.esps_udpinval++;
251 		return EINVAL;
252 	}
253 
254 	if (!udpencap && (tdbp->tdb_flags & TDBF_UDPENCAP)) {
255 		DPRINTF(("ipsec_common_input(): attempted to use udpencap "
256 		    "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf,
257 		    sizeof(buf)), ntohl(spi), tdbp->tdb_sproto));
258 		m_freem(m);
259 		espstat.esps_udpneeded++;
260 		return EINVAL;
261 	}
262 
263 	if (tdbp->tdb_xform == NULL) {
264 		DPRINTF(("ipsec_common_input(): attempted to use uninitialized "
265 		    "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf,
266 		    sizeof(buf)), ntohl(spi), tdbp->tdb_sproto));
267 		m_freem(m);
268 		IPSEC_ISTAT(espstat.esps_noxform, ahstat.ahs_noxform,
269 		    ipcompstat.ipcomps_noxform);
270 		return ENXIO;
271 	}
272 
273 	if (sproto != IPPROTO_IPCOMP) {
274 		if ((encif = enc_getif(tdbp->tdb_rdomain,
275 		    tdbp->tdb_tap)) == NULL) {
276 			DPRINTF(("ipsec_common_input(): "
277 			    "no enc%u interface for SA %s/%08x/%u\n",
278 			    tdbp->tdb_tap, ipsp_address(&dst_address, buf,
279 			    sizeof(buf)), ntohl(spi), tdbp->tdb_sproto));
280 			m_freem(m);
281 
282 			IPSEC_ISTAT(espstat.esps_pdrops,
283 			    ahstat.ahs_pdrops,
284 			    ipcompstat.ipcomps_pdrops);
285 			return EACCES;
286 		}
287 
288 		/* XXX This conflicts with the scoped nature of IPv6 */
289 		m->m_pkthdr.ph_ifidx = encif->if_index;
290 	}
291 
292 	/* Register first use, setup expiration timer. */
293 	if (tdbp->tdb_first_use == 0) {
294 		tdbp->tdb_first_use = time_second;
295 		if (tdbp->tdb_flags & TDBF_FIRSTUSE)
296 			timeout_add_sec(&tdbp->tdb_first_tmo,
297 			    tdbp->tdb_exp_first_use);
298 		if (tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE)
299 			timeout_add_sec(&tdbp->tdb_sfirst_tmo,
300 			    tdbp->tdb_soft_first_use);
301 	}
302 
303 	/*
304 	 * Call appropriate transform and return -- callback takes care of
305 	 * everything else.
306 	 */
307 	error = (*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff);
308 	return error;
309 }
310 
311 /*
312  * IPsec input callback, called by the transform callback. Takes care of
313  * filtering and other sanity checks on the processed packet.
314  */
315 void
316 ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
317 {
318 	int af, sproto;
319 	u_int8_t prot;
320 
321 #if NBPFILTER > 0
322 	struct ifnet *encif;
323 #endif
324 
325 	struct ip *ip, ipn;
326 
327 #ifdef INET6
328 	struct ip6_hdr *ip6, ip6n;
329 #endif /* INET6 */
330 	struct m_tag *mtag;
331 	struct tdb_ident *tdbi;
332 
333 #ifdef ENCDEBUG
334 	char buf[INET6_ADDRSTRLEN];
335 #endif
336 
337 	af = tdbp->tdb_dst.sa.sa_family;
338 	sproto = tdbp->tdb_sproto;
339 
340 	tdbp->tdb_last_used = time_second;
341 
342 	/* Sanity check */
343 	if (m == NULL) {
344 		/* The called routine will print a message if necessary */
345 		IPSEC_ISTAT(espstat.esps_badkcr, ahstat.ahs_badkcr,
346 		    ipcompstat.ipcomps_badkcr);
347 		return;
348 	}
349 
350 	/* Fix IPv4 header */
351 	if (af == AF_INET) {
352 		if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) {
353 			DPRINTF(("ipsec_common_input_cb(): processing failed "
354 			    "for SA %s/%08x\n", ipsp_address(&tdbp->tdb_dst,
355 			    buf, sizeof(buf)), ntohl(tdbp->tdb_spi)));
356 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
357 			    ipcompstat.ipcomps_hdrops);
358 			return;
359 		}
360 
361 		ip = mtod(m, struct ip *);
362 		ip->ip_len = htons(m->m_pkthdr.len);
363 		ip->ip_sum = 0;
364 		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
365 		prot = ip->ip_p;
366 
367 		/* IP-in-IP encapsulation */
368 		if (prot == IPPROTO_IPIP) {
369 			if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
370 				m_freem(m);
371 				IPSEC_ISTAT(espstat.esps_hdrops,
372 				    ahstat.ahs_hdrops,
373 				    ipcompstat.ipcomps_hdrops);
374 				return;
375 			}
376 			/* ipn will now contain the inner IPv4 header */
377 			m_copydata(m, skip, sizeof(struct ip),
378 			    (caddr_t) &ipn);
379 		}
380 
381 #ifdef INET6
382 		/* IPv6-in-IP encapsulation. */
383 		if (prot == IPPROTO_IPV6) {
384 			if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
385 				m_freem(m);
386 				IPSEC_ISTAT(espstat.esps_hdrops,
387 				    ahstat.ahs_hdrops,
388 				    ipcompstat.ipcomps_hdrops);
389 				return;
390 			}
391 			/* ip6n will now contain the inner IPv6 header. */
392 			m_copydata(m, skip, sizeof(struct ip6_hdr),
393 			    (caddr_t) &ip6n);
394 		}
395 #endif /* INET6 */
396 	}
397 
398 #ifdef INET6
399 	/* Fix IPv6 header */
400 	if (af == AF_INET6)
401 	{
402 		if (m->m_len < sizeof(struct ip6_hdr) &&
403 		    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
404 
405 			DPRINTF(("ipsec_common_input_cb(): processing failed "
406 			    "for SA %s/%08x\n", ipsp_address(&tdbp->tdb_dst,
407 			    buf, sizeof(buf)), ntohl(tdbp->tdb_spi)));
408 
409 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
410 			    ipcompstat.ipcomps_hdrops);
411 			return;
412 		}
413 
414 		ip6 = mtod(m, struct ip6_hdr *);
415 		ip6->ip6_plen = htons(m->m_pkthdr.len - skip);
416 
417 		/* Save protocol */
418 		m_copydata(m, protoff, 1, (caddr_t) &prot);
419 
420 		/* IP-in-IP encapsulation */
421 		if (prot == IPPROTO_IPIP) {
422 			if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
423 				m_freem(m);
424 				IPSEC_ISTAT(espstat.esps_hdrops,
425 				    ahstat.ahs_hdrops,
426 				    ipcompstat.ipcomps_hdrops);
427 				return;
428 			}
429 			/* ipn will now contain the inner IPv4 header */
430 			m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
431 		}
432 
433 		/* IPv6-in-IP encapsulation */
434 		if (prot == IPPROTO_IPV6) {
435 			if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
436 				m_freem(m);
437 				IPSEC_ISTAT(espstat.esps_hdrops,
438 				    ahstat.ahs_hdrops,
439 				    ipcompstat.ipcomps_hdrops);
440 				return;
441 			}
442 			/* ip6n will now contain the inner IPv6 header. */
443 			m_copydata(m, skip, sizeof(struct ip6_hdr),
444 			    (caddr_t) &ip6n);
445 		}
446 	}
447 #endif /* INET6 */
448 
449 	/*
450 	 * Fix TCP/UDP checksum of UDP encapsulated transport mode ESP packet.
451 	 * (RFC3948 3.1.2)
452 	 */
453 	if ((af == AF_INET || af == AF_INET6) &&
454 	    (tdbp->tdb_flags & TDBF_UDPENCAP) &&
455 	    (tdbp->tdb_flags & TDBF_TUNNELING) == 0) {
456 		u_int16_t cksum;
457 
458 		switch (prot) {
459 		case IPPROTO_UDP:
460 			if (m->m_pkthdr.len < skip + sizeof(struct udphdr)) {
461 				m_freem(m);
462 				IPSEC_ISTAT(espstat.esps_hdrops,
463 				    ahstat.ahs_hdrops,
464 				    ipcompstat.ipcomps_hdrops);
465 				return;
466 			}
467 			cksum = 0;
468 			m_copyback(m, skip + offsetof(struct udphdr, uh_sum),
469 			    sizeof(cksum), &cksum, M_NOWAIT);
470 #ifdef INET6
471 			if (af == AF_INET6) {
472 				cksum = in6_cksum(m, IPPROTO_UDP, skip,
473 				    m->m_pkthdr.len - skip);
474 				m_copyback(m, skip + offsetof(struct udphdr,
475 				    uh_sum), sizeof(cksum), &cksum, M_NOWAIT);
476 			}
477 #endif
478 			break;
479 		case IPPROTO_TCP:
480 			if (m->m_pkthdr.len < skip + sizeof(struct tcphdr)) {
481 				m_freem(m);
482 				IPSEC_ISTAT(espstat.esps_hdrops,
483 				    ahstat.ahs_hdrops,
484 				    ipcompstat.ipcomps_hdrops);
485 				return;
486 			}
487 			cksum = 0;
488 			m_copyback(m, skip + offsetof(struct tcphdr, th_sum),
489 			    sizeof(cksum), &cksum, M_NOWAIT);
490 			if (af == AF_INET)
491 				cksum = in4_cksum(m, IPPROTO_TCP, skip,
492 				    m->m_pkthdr.len - skip);
493 #ifdef INET6
494 			else if (af == AF_INET6)
495 				cksum = in6_cksum(m, IPPROTO_TCP, skip,
496 				    m->m_pkthdr.len - skip);
497 #endif
498 			m_copyback(m, skip + offsetof(struct tcphdr, th_sum),
499 			    sizeof(cksum), &cksum, M_NOWAIT);
500 			break;
501 		}
502 	}
503 
504 	/*
505 	 * Record what we've done to the packet (under what SA it was
506 	 * processed).
507 	 */
508 	if (tdbp->tdb_sproto != IPPROTO_IPCOMP) {
509 		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
510 		    sizeof(struct tdb_ident), M_NOWAIT);
511 		if (mtag == NULL) {
512 			m_freem(m);
513 			DPRINTF(("ipsec_common_input_cb(): failed to "
514 			    "get tag\n"));
515 			IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
516 			    ipcompstat.ipcomps_hdrops);
517 			return;
518 		}
519 
520 		tdbi = (struct tdb_ident *)(mtag + 1);
521 		bcopy(&tdbp->tdb_dst, &tdbi->dst,
522 		    sizeof(union sockaddr_union));
523 		tdbi->proto = tdbp->tdb_sproto;
524 		tdbi->spi = tdbp->tdb_spi;
525 		tdbi->rdomain = tdbp->tdb_rdomain;
526 
527 		m_tag_prepend(m, mtag);
528 	}
529 
530 	if (sproto == IPPROTO_ESP) {
531 		/* Packet is confidential ? */
532 		if (tdbp->tdb_encalgxform)
533 			m->m_flags |= M_CONF;
534 
535 		/* Check if we had authenticated ESP. */
536 		if (tdbp->tdb_authalgxform)
537 			m->m_flags |= M_AUTH;
538 	} else if (sproto == IPPROTO_AH) {
539 		m->m_flags |= M_AUTH;
540 	} else if (sproto == IPPROTO_IPCOMP) {
541 		m->m_flags |= M_COMP;
542 	}
543 
544 #if NPF > 0
545 	/* Add pf tag if requested. */
546 	pf_tag_packet(m, tdbp->tdb_tag, -1);
547 	pf_pkt_addr_changed(m);
548 #endif
549 
550 	if (tdbp->tdb_flags & TDBF_TUNNELING)
551 		m->m_flags |= M_TUNNEL;
552 
553 #if NBPFILTER > 0
554 	if ((encif = enc_getif(tdbp->tdb_rdomain, tdbp->tdb_tap)) != NULL) {
555 		encif->if_ipackets++;
556 		encif->if_ibytes += m->m_pkthdr.len;
557 
558 		if (encif->if_bpf) {
559 			struct enchdr hdr;
560 
561 			hdr.af = af;
562 			hdr.spi = tdbp->tdb_spi;
563 			hdr.flags = m->m_flags & (M_AUTH|M_CONF);
564 
565 			bpf_mtap_hdr(encif->if_bpf, (char *)&hdr,
566 			    ENC_HDRLEN, m, BPF_DIRECTION_IN, NULL);
567 		}
568 	}
569 #endif
570 
571 	switch (sproto) {
572 	case IPPROTO_ESP:
573 	case IPPROTO_AH:
574 	case IPPROTO_IPCOMP:
575 		break;
576 	default:
577 		DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
578 		    " security protocol %d\n", sproto));
579 		m_freem(m);
580 		return;
581 	}
582 
583 	/* Call the appropriate IPsec transform callback. */
584 	switch (af) {
585 	case AF_INET:
586 		if (niq_enqueue(&ipintrq, m) != 0) {
587 			DPRINTF(("ipsec_common_input_cb(): dropped packet "
588 			    "because of full IP queue\n"));
589 			IPSEC_ISTAT(espstat.esps_qfull, ahstat.ahs_qfull,
590 			    ipcompstat.ipcomps_qfull);
591 		}
592 		return;
593 #ifdef INET6
594 	case AF_INET6:
595 		ip6_local(m, skip, prot);
596 		return;
597 #endif /* INET6 */
598 	default:
599 		DPRINTF(("ipsec_common_input_cb(): unknown/unsupported "
600 		    "protocol family %d\n", af));
601 		m_freem(m);
602 		return;
603 	}
604 #undef IPSEC_ISTAT
605 }
606 
607 int
608 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 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_STATS:
617 		if (newp != NULL)
618 			return (EPERM);
619 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
620 		    &espstat, sizeof(espstat)));
621 	default:
622 		if (name[0] < ESPCTL_MAXID)
623 			return (sysctl_int_arr(espctl_vars, name, namelen,
624 			    oldp, oldlenp, newp, newlen));
625 		return (ENOPROTOOPT);
626 	}
627 }
628 
629 int
630 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
631     size_t newlen)
632 {
633 	/* All sysctl names at this level are terminal. */
634 	if (namelen != 1)
635 		return (ENOTDIR);
636 
637 	switch (name[0]) {
638 	case AHCTL_STATS:
639 		if (newp != NULL)
640 			return (EPERM);
641 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
642 		    &ahstat, sizeof(ahstat)));
643 	default:
644 		if (name[0] < AHCTL_MAXID)
645 			return (sysctl_int_arr(ahctl_vars, name, namelen,
646 			    oldp, oldlenp, newp, newlen));
647 		return (ENOPROTOOPT);
648 	}
649 }
650 
651 int
652 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 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 IPCOMPCTL_STATS:
661 		if (newp != NULL)
662 			return (EPERM);
663 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
664 		    &ipcompstat, sizeof(ipcompstat)));
665 	default:
666 		if (name[0] < IPCOMPCTL_MAXID)
667 			return (sysctl_int_arr(ipcompctl_vars, name, namelen,
668 			    oldp, oldlenp, newp, newlen));
669 		return (ENOPROTOOPT);
670 	}
671 }
672 
673 /* IPv4 AH wrapper. */
674 int
675 ah4_input(struct mbuf **mp, int *offp, int proto)
676 {
677 	ipsec_common_input(*mp, *offp, offsetof(struct ip, ip_p), AF_INET,
678 	    proto, 0);
679 	return IPPROTO_DONE;
680 }
681 
682 /* XXX rdomain */
683 void
684 ah4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
685 {
686 	if (sa->sa_family != AF_INET ||
687 	    sa->sa_len != sizeof(struct sockaddr_in))
688 		return;
689 
690 	ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_AH);
691 }
692 
693 /* IPv4 ESP wrapper. */
694 int
695 esp4_input(struct mbuf **mp, int *offp, int proto)
696 {
697 	ipsec_common_input(*mp, *offp, offsetof(struct ip, ip_p), AF_INET,
698 	    proto, 0);
699 	return IPPROTO_DONE;
700 }
701 
702 /* IPv4 IPCOMP wrapper */
703 int
704 ipcomp4_input(struct mbuf **mp, int *offp, int proto)
705 {
706 	ipsec_common_input(*mp, *offp, offsetof(struct ip, ip_p), AF_INET,
707 	    proto, 0);
708 	return IPPROTO_DONE;
709 }
710 
711 void
712 ipsec_common_ctlinput(u_int rdomain, int cmd, struct sockaddr *sa,
713     void *v, int proto)
714 {
715 	struct ip *ip = v;
716 
717 	if (cmd == PRC_MSGSIZE && ip && ip_mtudisc && ip->ip_v == 4) {
718 		struct tdb *tdbp;
719 		struct sockaddr_in dst;
720 		struct icmp *icp;
721 		int hlen = ip->ip_hl << 2;
722 		u_int32_t spi, mtu;
723 		ssize_t adjust;
724 
725 		/* Find the right MTU. */
726 		icp = (struct icmp *)((caddr_t) ip -
727 		    offsetof(struct icmp, icmp_ip));
728 		mtu = ntohs(icp->icmp_nextmtu);
729 
730 		/*
731 		 * Ignore the packet, if we do not receive a MTU
732 		 * or the MTU is too small to be acceptable.
733 		 */
734 		if (mtu < 296)
735 			return;
736 
737 		memset(&dst, 0, sizeof(struct sockaddr_in));
738 		dst.sin_family = AF_INET;
739 		dst.sin_len = sizeof(struct sockaddr_in);
740 		dst.sin_addr.s_addr = ip->ip_dst.s_addr;
741 
742 		bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t));
743 
744 		tdbp = gettdb(rdomain, spi, (union sockaddr_union *)&dst,
745 		    proto);
746 		if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID)
747 			return;
748 
749 		/* Walk the chain backwards to the first tdb */
750 		for (; tdbp; tdbp = tdbp->tdb_inext) {
751 			if (tdbp->tdb_flags & TDBF_INVALID ||
752 			    (adjust = ipsec_hdrsz(tdbp)) == -1)
753 				return;
754 
755 			mtu -= adjust;
756 
757 			/* Store adjusted MTU in tdb */
758 			tdbp->tdb_mtu = mtu;
759 			tdbp->tdb_mtutimeout = time_second +
760 			    ip_mtudisc_timeout;
761 			DPRINTF(("ipsec_common_ctlinput: "
762 			    "spi %08x mtu %d adjust %ld\n",
763 			    ntohl(tdbp->tdb_spi), tdbp->tdb_mtu,
764 			    adjust));
765 		}
766 	}
767 }
768 
769 /* XXX rdomain */
770 void
771 udpencap_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
772 {
773 	struct ip *ip = v;
774 	struct tdb *tdbp;
775 	struct icmp *icp;
776 	u_int32_t mtu;
777 	ssize_t adjust;
778 	struct sockaddr_in dst, src;
779 	union sockaddr_union *su_dst, *su_src;
780 
781 	splsoftassert(IPL_SOFTNET);
782 
783 	icp = (struct icmp *)((caddr_t) ip - offsetof(struct icmp, icmp_ip));
784 	mtu = ntohs(icp->icmp_nextmtu);
785 
786 	/*
787 	 * Ignore the packet, if we do not receive a MTU
788 	 * or the MTU is too small to be acceptable.
789 	 */
790 	if (mtu < 296)
791 		return;
792 
793 	memset(&dst, 0, sizeof(dst));
794 	dst.sin_family = AF_INET;
795 	dst.sin_len = sizeof(struct sockaddr_in);
796 	dst.sin_addr.s_addr = ip->ip_dst.s_addr;
797 	su_dst = (union sockaddr_union *)&dst;
798 	memset(&src, 0, sizeof(src));
799 	src.sin_family = AF_INET;
800 	src.sin_len = sizeof(struct sockaddr_in);
801 	src.sin_addr.s_addr = ip->ip_src.s_addr;
802 	su_src = (union sockaddr_union *)&src;
803 
804 	tdbp = gettdbbysrcdst(rdomain, 0, su_src, su_dst, IPPROTO_ESP);
805 
806 	for (; tdbp != NULL; tdbp = tdbp->tdb_snext) {
807 		if (tdbp->tdb_sproto == IPPROTO_ESP &&
808 		    ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_UDPENCAP)) ==
809 		    TDBF_UDPENCAP) &&
810 		    !memcmp(&tdbp->tdb_dst, &dst, SA_LEN(&su_dst->sa)) &&
811 		    !memcmp(&tdbp->tdb_src, &src, SA_LEN(&su_src->sa))) {
812 			if ((adjust = ipsec_hdrsz(tdbp)) != -1) {
813 				/* Store adjusted MTU in tdb */
814 				tdbp->tdb_mtu = mtu - adjust;
815 				tdbp->tdb_mtutimeout = time_second +
816 				    ip_mtudisc_timeout;
817 				DPRINTF(("udpencap_ctlinput: "
818 				    "spi %08x mtu %d adjust %ld\n",
819 				    ntohl(tdbp->tdb_spi), tdbp->tdb_mtu,
820 				    adjust));
821 			}
822 		}
823 	}
824 }
825 
826 /* XXX rdomain */
827 void
828 esp4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
829 {
830 	if (sa->sa_family != AF_INET ||
831 	    sa->sa_len != sizeof(struct sockaddr_in))
832 		return;
833 
834 	ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_ESP);
835 }
836 
837 #ifdef INET6
838 /* IPv6 AH wrapper. */
839 int
840 ah6_input(struct mbuf **mp, int *offp, int proto)
841 {
842 	int l = 0;
843 	int protoff, nxt;
844 	struct ip6_ext ip6e;
845 
846 	if (*offp < sizeof(struct ip6_hdr)) {
847 		DPRINTF(("ah6_input(): bad offset\n"));
848 		ahstat.ahs_hdrops++;
849 		m_freem(*mp);
850 		*mp = NULL;
851 		return IPPROTO_DONE;
852 	} else if (*offp == sizeof(struct ip6_hdr)) {
853 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
854 	} else {
855 		/* Chase down the header chain... */
856 		protoff = sizeof(struct ip6_hdr);
857 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
858 
859 		do {
860 			protoff += l;
861 			m_copydata(*mp, protoff, sizeof(ip6e),
862 			    (caddr_t) &ip6e);
863 
864 			if (nxt == IPPROTO_AH)
865 				l = (ip6e.ip6e_len + 2) << 2;
866 			else
867 				l = (ip6e.ip6e_len + 1) << 3;
868 #ifdef DIAGNOSTIC
869 			if (l <= 0)
870 				panic("ah6_input: l went zero or negative");
871 #endif
872 
873 			nxt = ip6e.ip6e_nxt;
874 		} while (protoff + l < *offp);
875 
876 		/* Malformed packet check */
877 		if (protoff + l != *offp) {
878 			DPRINTF(("ah6_input(): bad packet header chain\n"));
879 			ahstat.ahs_hdrops++;
880 			m_freem(*mp);
881 			*mp = NULL;
882 			return IPPROTO_DONE;
883 		}
884 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
885 	}
886 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0);
887 	return IPPROTO_DONE;
888 }
889 
890 /* IPv6 ESP wrapper. */
891 int
892 esp6_input(struct mbuf **mp, int *offp, int proto)
893 {
894 	int l = 0;
895 	int protoff, nxt;
896 	struct ip6_ext ip6e;
897 
898 	if (*offp < sizeof(struct ip6_hdr)) {
899 		DPRINTF(("esp6_input(): bad offset\n"));
900 		espstat.esps_hdrops++;
901 		m_freem(*mp);
902 		*mp = NULL;
903 		return IPPROTO_DONE;
904 	} else if (*offp == sizeof(struct ip6_hdr)) {
905 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
906 	} else {
907 		/* Chase down the header chain... */
908 		protoff = sizeof(struct ip6_hdr);
909 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
910 
911 		do {
912 			protoff += l;
913 			m_copydata(*mp, protoff, sizeof(ip6e),
914 			    (caddr_t) &ip6e);
915 
916 			if (nxt == IPPROTO_AH)
917 				l = (ip6e.ip6e_len + 2) << 2;
918 			else
919 				l = (ip6e.ip6e_len + 1) << 3;
920 #ifdef DIAGNOSTIC
921 			if (l <= 0)
922 				panic("esp6_input: l went zero or negative");
923 #endif
924 
925 			nxt = ip6e.ip6e_nxt;
926 		} while (protoff + l < *offp);
927 
928 		/* Malformed packet check */
929 		if (protoff + l != *offp) {
930 			DPRINTF(("esp6_input(): bad packet header chain\n"));
931 			espstat.esps_hdrops++;
932 			m_freem(*mp);
933 			*mp = NULL;
934 			return IPPROTO_DONE;
935 		}
936 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
937 	}
938 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0);
939 	return IPPROTO_DONE;
940 
941 }
942 
943 /* IPv6 IPcomp wrapper */
944 int
945 ipcomp6_input(struct mbuf **mp, int *offp, int proto)
946 {
947 	int l = 0;
948 	int protoff, nxt;
949 	struct ip6_ext ip6e;
950 
951 	if (*offp < sizeof(struct ip6_hdr)) {
952 		DPRINTF(("ipcomp6_input(): bad offset\n"));
953 		ipcompstat.ipcomps_hdrops++;
954 		m_freem(*mp);
955 		*mp = NULL;
956 		return IPPROTO_DONE;
957 	} else if (*offp == sizeof(struct ip6_hdr)) {
958 		protoff = offsetof(struct ip6_hdr, ip6_nxt);
959 	} else {
960 		/* Chase down the header chain... */
961 		protoff = sizeof(struct ip6_hdr);
962 		nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
963 
964 		do {
965 			protoff += l;
966 			m_copydata(*mp, protoff, sizeof(ip6e),
967 			    (caddr_t) &ip6e);
968 			if (nxt == IPPROTO_AH)
969 				l = (ip6e.ip6e_len + 2) << 2;
970 			else
971 				l = (ip6e.ip6e_len + 1) << 3;
972 #ifdef DIAGNOSTIC
973 			if (l <= 0)
974 				panic("ipcomp6_input: l went zero or negative");
975 #endif
976 
977 			nxt = ip6e.ip6e_nxt;
978 		} while (protoff + l < *offp);
979 
980 		/* Malformed packet check */
981 		if (protoff + l != *offp) {
982 			DPRINTF(("ipcomp6_input(): bad packet header chain\n"));
983 			ipcompstat.ipcomps_hdrops++;
984 			m_freem(*mp);
985 			*mp = NULL;
986 			return IPPROTO_DONE;
987 		}
988 
989 		protoff += offsetof(struct ip6_ext, ip6e_nxt);
990 	}
991 	ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0);
992 	return IPPROTO_DONE;
993 }
994 #endif /* INET6 */
995