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