This source file includes following definitions.
- ipsec_common_input
- ipsec_common_input_cb
- esp_sysctl
- ah_sysctl
- ipcomp_sysctl
- ah4_input
- ah4_input_cb
- ah4_ctlinput
- esp4_input
- esp4_input_cb
- ipcomp4_input
- ipcomp4_input_cb
- ipsec_common_ctlinput
- udpencap_ctlinput
- esp4_ctlinput
- ah6_input
- ah6_input_cb
- esp6_input
- esp6_input_cb
- ipcomp6_input
- ipcomp6_input_cb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
48 #include <net/if.h>
49 #include <net/netisr.h>
50 #include <net/bpf.h>
51
52 #if NPF > 0
53 #include <net/pfvar.h>
54 #endif
55
56 #include <netinet/in.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/ip.h>
59 #include <netinet/ip_var.h>
60 #include <netinet/in_var.h>
61 #include <netinet/ip_icmp.h>
62 #include <netinet/tcp.h>
63 #include <netinet/udp.h>
64
65 #ifdef INET6
66 #ifndef INET
67 #include <netinet/in.h>
68 #endif
69 #include <netinet/ip6.h>
70 #include <netinet6/ip6_var.h>
71 #include <netinet6/ip6protosw.h>
72 #endif
73
74 #include <netinet/ip_ipsp.h>
75 #include <netinet/ip_esp.h>
76 #include <netinet/ip_ah.h>
77 #include <netinet/ip_ipcomp.h>
78
79 #include <net/if_enc.h>
80
81 #include "bpfilter.h"
82
83 void *ipsec_common_ctlinput(int, struct sockaddr *, void *, int);
84
85 #ifdef ENCDEBUG
86 #define DPRINTF(x) if (encdebug) printf x
87 #else
88 #define DPRINTF(x)
89 #endif
90
91
92 int esp_enable = 1;
93 int ah_enable = 1;
94 int ipcomp_enable = 0;
95
96 int *espctl_vars[ESPCTL_MAXID] = ESPCTL_VARS;
97 int *ahctl_vars[AHCTL_MAXID] = AHCTL_VARS;
98 int *ipcompctl_vars[IPCOMPCTL_MAXID] = IPCOMPCTL_VARS;
99
100 #ifdef INET6
101 extern struct ip6protosw inet6sw[];
102 extern u_char ip6_protox[];
103 #endif
104
105
106
107
108
109
110
111 int
112 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto,
113 int udpencap)
114 {
115 #define IPSEC_ISTAT(x,y,z) (sproto == IPPROTO_ESP ? (x)++ : \
116 sproto == IPPROTO_AH ? (y)++ : (z)++)
117
118 union sockaddr_union dst_address;
119 struct timeval tv;
120 struct tdb *tdbp;
121 u_int32_t spi;
122 u_int16_t cpi;
123 int s, error;
124
125 IPSEC_ISTAT(espstat.esps_input, ahstat.ahs_input,
126 ipcompstat.ipcomps_input);
127
128 if (m == 0) {
129 DPRINTF(("ipsec_common_input(): NULL packet received\n"));
130 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
131 ipcompstat.ipcomps_hdrops);
132 return EINVAL;
133 }
134
135 if ((sproto == IPPROTO_ESP && !esp_enable) ||
136 (sproto == IPPROTO_AH && !ah_enable) ||
137 (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
138 rip_input(m, skip, sproto);
139 return 0;
140 }
141
142 if (m->m_pkthdr.len - skip < 2 * sizeof(u_int32_t)) {
143 m_freem(m);
144 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
145 ipcompstat.ipcomps_hdrops);
146 DPRINTF(("ipsec_common_input(): packet too small\n"));
147 return EINVAL;
148 }
149
150
151 if (sproto == IPPROTO_ESP)
152 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
153 else if (sproto == IPPROTO_AH)
154 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
155 (caddr_t) &spi);
156 else if (sproto == IPPROTO_IPCOMP) {
157 m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t),
158 (caddr_t) &cpi);
159 spi = ntohl(htons(cpi));
160 }
161
162
163
164
165
166
167
168 bzero(&dst_address, sizeof(dst_address));
169 dst_address.sa.sa_family = af;
170
171 switch (af) {
172 #ifdef INET
173 case AF_INET:
174 dst_address.sin.sin_len = sizeof(struct sockaddr_in);
175 m_copydata(m, offsetof(struct ip, ip_dst),
176 sizeof(struct in_addr),
177 (caddr_t) &(dst_address.sin.sin_addr));
178 break;
179 #endif
180
181 #ifdef INET6
182 case AF_INET6:
183 dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
184 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
185 sizeof(struct in6_addr),
186 (caddr_t) &(dst_address.sin6.sin6_addr));
187 in6_recoverscope(&dst_address.sin6, &dst_address.sin6.sin6_addr,
188 NULL);
189 break;
190 #endif
191
192 default:
193 DPRINTF(("ipsec_common_input(): unsupported protocol "
194 "family %d\n", af));
195 m_freem(m);
196 IPSEC_ISTAT(espstat.esps_nopf, ahstat.ahs_nopf,
197 ipcompstat.ipcomps_nopf);
198 return EPFNOSUPPORT;
199 }
200
201 s = spltdb();
202 tdbp = gettdb(spi, &dst_address, sproto);
203 if (tdbp == NULL) {
204 splx(s);
205 DPRINTF(("ipsec_common_input(): could not find SA for "
206 "packet to %s, spi %08x\n",
207 ipsp_address(dst_address), ntohl(spi)));
208 m_freem(m);
209 IPSEC_ISTAT(espstat.esps_notdb, ahstat.ahs_notdb,
210 ipcompstat.ipcomps_notdb);
211 return ENOENT;
212 }
213
214 if (tdbp->tdb_flags & TDBF_INVALID) {
215 splx(s);
216 DPRINTF(("ipsec_common_input(): attempted to use invalid SA %s/%08x/%u\n", ipsp_address(dst_address), ntohl(spi), tdbp->tdb_sproto));
217 m_freem(m);
218 IPSEC_ISTAT(espstat.esps_invalid, ahstat.ahs_invalid,
219 ipcompstat.ipcomps_invalid);
220 return EINVAL;
221 }
222
223 if (udpencap && !(tdbp->tdb_flags & TDBF_UDPENCAP)) {
224 splx(s);
225 DPRINTF(("ipsec_common_input(): attempted to use non-udpencap SA %s/%08x/%u\n", ipsp_address(dst_address), ntohl(spi), tdbp->tdb_sproto));
226 m_freem(m);
227 espstat.esps_udpinval++;
228 return EINVAL;
229 }
230
231 if (tdbp->tdb_xform == NULL) {
232 splx(s);
233 DPRINTF(("ipsec_common_input(): attempted to use uninitialized SA %s/%08x/%u\n", ipsp_address(dst_address), ntohl(spi), tdbp->tdb_sproto));
234 m_freem(m);
235 IPSEC_ISTAT(espstat.esps_noxform, ahstat.ahs_noxform,
236 ipcompstat.ipcomps_noxform);
237 return ENXIO;
238 }
239
240 if (tdbp->tdb_dst.sa.sa_family == AF_INET &&
241 sproto != IPPROTO_IPCOMP) {
242
243
244
245
246 m->m_pkthdr.rcvif = &encif[0].sc_if;
247 }
248
249
250 if (tdbp->tdb_first_use == 0) {
251 tdbp->tdb_first_use = time_second;
252
253 tv.tv_usec = 0;
254
255 tv.tv_sec = tdbp->tdb_exp_first_use + tdbp->tdb_first_use;
256 if (tdbp->tdb_flags & TDBF_FIRSTUSE)
257 timeout_add(&tdbp->tdb_first_tmo, hzto(&tv));
258
259 tv.tv_sec = tdbp->tdb_first_use + tdbp->tdb_soft_first_use;
260 if (tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE)
261 timeout_add(&tdbp->tdb_sfirst_tmo, hzto(&tv));
262 }
263
264
265
266
267
268 error = (*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff);
269 splx(s);
270 return error;
271 }
272
273
274
275
276
277 int
278 ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
279 struct m_tag *mt)
280 {
281 int prot, af, sproto;
282
283 #if NBPFILTER > 0
284 struct ifnet *bpfif;
285 #endif
286
287 #ifdef INET
288 struct ip *ip, ipn;
289 #endif
290
291 #ifdef INET6
292 struct ip6_hdr *ip6, ip6n;
293 #endif
294 struct m_tag *mtag;
295 struct tdb_ident *tdbi;
296
297 af = tdbp->tdb_dst.sa.sa_family;
298 sproto = tdbp->tdb_sproto;
299
300 tdbp->tdb_last_used = time_second;
301
302
303 if (m == NULL) {
304
305 IPSEC_ISTAT(espstat.esps_badkcr, ahstat.ahs_badkcr,
306 ipcompstat.ipcomps_badkcr);
307 return EINVAL;
308 }
309
310 #ifdef INET
311
312 if (tdbp->tdb_dst.sa.sa_family == AF_INET) {
313 if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) {
314 DPRINTF(("ipsec_common_input_cb(): processing failed "
315 "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst),
316 ntohl(tdbp->tdb_spi)));
317 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
318 ipcompstat.ipcomps_hdrops);
319 return ENOBUFS;
320 }
321
322 ip = mtod(m, struct ip *);
323 ip->ip_len = htons(m->m_pkthdr.len);
324 ip->ip_sum = 0;
325 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
326 prot = ip->ip_p;
327
328
329 if (prot == IPPROTO_IPIP) {
330 if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
331 m_freem(m);
332 IPSEC_ISTAT(espstat.esps_hdrops,
333 ahstat.ahs_hdrops,
334 ipcompstat.ipcomps_hdrops);
335 return EINVAL;
336 }
337
338 m_copydata(m, skip, sizeof(struct ip),
339 (caddr_t) &ipn);
340
341
342
343
344
345 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET &&
346 tdbp->tdb_proxy.sin.sin_addr.s_addr !=
347 INADDR_ANY &&
348 ipn.ip_src.s_addr !=
349 tdbp->tdb_proxy.sin.sin_addr.s_addr) ||
350 (tdbp->tdb_proxy.sa.sa_family != AF_INET &&
351 tdbp->tdb_proxy.sa.sa_family != 0)) {
352
353 DPRINTF(("ipsec_common_input_cb(): inner "
354 "source address %s doesn't correspond to "
355 "expected proxy source %s, SA %s/%08x\n",
356 inet_ntoa4(ipn.ip_src),
357 ipsp_address(tdbp->tdb_proxy),
358 ipsp_address(tdbp->tdb_dst),
359 ntohl(tdbp->tdb_spi)));
360
361 m_freem(m);
362 IPSEC_ISTAT(espstat.esps_pdrops,
363 ahstat.ahs_pdrops,
364 ipcompstat.ipcomps_pdrops);
365 return EACCES;
366 }
367 }
368
369 #if INET6
370
371 if (prot == IPPROTO_IPV6) {
372 if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
373 m_freem(m);
374 IPSEC_ISTAT(espstat.esps_hdrops,
375 ahstat.ahs_hdrops,
376 ipcompstat.ipcomps_hdrops);
377 return EINVAL;
378 }
379
380 m_copydata(m, skip, sizeof(struct ip6_hdr),
381 (caddr_t) &ip6n);
382
383
384
385
386
387 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 &&
388 !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) &&
389 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
390 &tdbp->tdb_proxy.sin6.sin6_addr)) ||
391 (tdbp->tdb_proxy.sa.sa_family != AF_INET6 &&
392 tdbp->tdb_proxy.sa.sa_family != 0)) {
393
394 DPRINTF(("ipsec_common_input_cb(): inner "
395 "source address %s doesn't correspond to "
396 "expected proxy source %s, SA %s/%08x\n",
397 ip6_sprintf(&ip6n.ip6_src),
398 ipsp_address(tdbp->tdb_proxy),
399 ipsp_address(tdbp->tdb_dst),
400 ntohl(tdbp->tdb_spi)));
401
402 m_freem(m);
403 IPSEC_ISTAT(espstat.esps_pdrops,
404 ahstat.ahs_pdrops,
405 ipcompstat.ipcomps_pdrops);
406 return EACCES;
407 }
408 }
409 #endif
410 }
411 #endif
412
413 #ifdef INET6
414
415 if (af == INET6)
416 {
417 if (m->m_len < sizeof(struct ip6_hdr) &&
418 (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
419
420 DPRINTF(("ipsec_common_input_cb(): processing failed "
421 "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst),
422 ntohl(tdbp->tdb_spi)));
423
424 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
425 ipcompstat.ipcomps_hdrops);
426 return EACCES;
427 }
428
429 ip6 = mtod(m, struct ip6_hdr *);
430 ip6->ip6_plen = htons(m->m_pkthdr.len -
431 sizeof(struct ip6_hdr));
432
433
434 m_copydata(m, protoff, 1, (unsigned char *) &prot);
435
436 #ifdef INET
437
438 if (prot == IPPROTO_IPIP) {
439 if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
440 m_freem(m);
441 IPSEC_ISTAT(espstat.esps_hdrops,
442 ahstat.ahs_hdrops,
443 ipcompstat.ipcomps_hdrops);
444 return EINVAL;
445 }
446
447 m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
448
449
450
451
452
453 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET &&
454 tdbp->tdb_proxy.sin.sin_addr.s_addr !=
455 INADDR_ANY &&
456 ipn.ip_src.s_addr !=
457 tdbp->tdb_proxy.sin.sin_addr.s_addr) ||
458 (tdbp->tdb_proxy.sa.sa_family != AF_INET &&
459 tdbp->tdb_proxy.sa.sa_family != 0)) {
460
461 DPRINTF(("ipsec_common_input_cb(): inner "
462 "source address %s doesn't correspond to "
463 "expected proxy source %s, SA %s/%08x\n",
464 inet_ntoa4(ipn.ip_src),
465 ipsp_address(tdbp->tdb_proxy),
466 ipsp_address(tdbp->tdb_dst),
467 ntohl(tdbp->tdb_spi)));
468
469 m_freem(m);
470 IPSEC_ISTAT(espstat.esps_pdrops,
471 ahstat.ahs_pdrops,
472 ipcompstat.ipcomps_pdrops);
473 return EACCES;
474 }
475 }
476 #endif
477
478
479 if (prot == IPPROTO_IPV6) {
480 if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
481 m_freem(m);
482 IPSEC_ISTAT(espstat.esps_hdrops,
483 ahstat.ahs_hdrops,
484 ipcompstat.ipcomps_hdrops);
485 return EINVAL;
486 }
487
488 m_copydata(m, skip, sizeof(struct ip6_hdr),
489 (caddr_t) &ip6n);
490
491
492
493
494
495 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 &&
496 !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) &&
497 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
498 &tdbp->tdb_proxy.sin6.sin6_addr)) ||
499 (tdbp->tdb_proxy.sa.sa_family != AF_INET6 &&
500 tdbp->tdb_proxy.sa.sa_family != 0)) {
501
502 DPRINTF(("ipsec_common_input_cb(): inner "
503 "source address %s doesn't correspond to "
504 "expected proxy source %s, SA %s/%08x\n",
505 ip6_sprintf(&ip6n.ip6_src),
506 ipsp_address(tdbp->tdb_proxy),
507 ipsp_address(tdbp->tdb_dst),
508 ntohl(tdbp->tdb_spi)));
509
510 m_freem(m);
511 IPSEC_ISTAT(espstat.esps_pdrops,
512 ahstat.ahs_pdrops,
513 ipcompstat.ipcomps_pdrops);
514 return EACCES;
515 }
516 }
517 }
518 #endif
519
520
521
522
523
524
525
526
527
528 if (mt == NULL && tdbp->tdb_sproto != IPPROTO_IPCOMP) {
529 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
530 sizeof(struct tdb_ident), M_NOWAIT);
531 if (mtag == NULL) {
532 m_freem(m);
533 DPRINTF(("ipsec_common_input_cb(): failed to "
534 "get tag\n"));
535 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops,
536 ipcompstat.ipcomps_hdrops);
537 return ENOMEM;
538 }
539
540 tdbi = (struct tdb_ident *)(mtag + 1);
541 bcopy(&tdbp->tdb_dst, &tdbi->dst,
542 sizeof(union sockaddr_union));
543 tdbi->proto = tdbp->tdb_sproto;
544 tdbi->spi = tdbp->tdb_spi;
545
546 m_tag_prepend(m, mtag);
547 } else {
548 if (mt != NULL)
549 mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
550 }
551
552 if (sproto == IPPROTO_ESP) {
553
554 if (tdbp->tdb_encalgxform)
555 m->m_flags |= M_CONF;
556
557
558 if (tdbp->tdb_authalgxform)
559 m->m_flags |= M_AUTH;
560 } else if (sproto == IPPROTO_AH)
561 m->m_flags |= M_AUTH | M_AUTH_AH;
562
563 #if NPF > 0
564
565 if (pf_tag_packet(m, tdbp->tdb_tag, -1))
566 DPRINTF(("failed to tag ipsec packet\n"));
567 #endif
568
569 if (tdbp->tdb_flags & TDBF_TUNNELING)
570 m->m_flags |= M_TUNNEL;
571
572 #if NBPFILTER > 0
573 bpfif = &encif[0].sc_if;
574 bpfif->if_ipackets++;
575 bpfif->if_ibytes += m->m_pkthdr.len;
576
577 if (bpfif->if_bpf) {
578 struct enchdr hdr;
579
580 hdr.af = af;
581 hdr.spi = tdbp->tdb_spi;
582 hdr.flags = m->m_flags & (M_AUTH|M_CONF|M_AUTH_AH);
583
584 bpf_mtap_hdr(bpfif->if_bpf, (char *)&hdr, ENC_HDRLEN, m,
585 BPF_DIRECTION_IN);
586 }
587 #endif
588
589
590 switch (af) {
591 #ifdef INET
592 case AF_INET:
593 switch (sproto)
594 {
595 case IPPROTO_ESP:
596 return esp4_input_cb(m);
597
598 case IPPROTO_AH:
599 return ah4_input_cb(m);
600
601 case IPPROTO_IPCOMP:
602 return ipcomp4_input_cb(m);
603
604 default:
605 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
606 " security protocol %d\n", sproto));
607 m_freem(m);
608 return EPFNOSUPPORT;
609 }
610 break;
611 #endif
612
613 #ifdef INET6
614 case AF_INET6:
615 switch (sproto) {
616 case IPPROTO_ESP:
617 return esp6_input_cb(m, skip, protoff);
618
619 case IPPROTO_AH:
620 return ah6_input_cb(m, skip, protoff);
621
622 case IPPROTO_IPCOMP:
623 return ipcomp6_input_cb(m, skip, protoff);
624
625 default:
626 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
627 " security protocol %d\n", sproto));
628 m_freem(m);
629 return EPFNOSUPPORT;
630 }
631 break;
632 #endif
633
634 default:
635 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported "
636 "protocol family %d\n", af));
637 m_freem(m);
638 return EPFNOSUPPORT;
639 }
640 #undef IPSEC_ISTAT
641 }
642
643 int
644 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
645 size_t newlen)
646 {
647 if (name[0] < ESPCTL_MAXID)
648 return (sysctl_int_arr(espctl_vars, name, namelen,
649 oldp, oldlenp, newp, newlen));
650 return (ENOPROTOOPT);
651 }
652
653 int
654 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
655 size_t newlen)
656 {
657 if (name[0] < AHCTL_MAXID)
658 return (sysctl_int_arr(ahctl_vars, name, namelen,
659 oldp, oldlenp, newp, newlen));
660 return (ENOPROTOOPT);
661 }
662
663 int
664 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
665 size_t newlen)
666 {
667 if (name[0] < IPCOMPCTL_MAXID)
668 return (sysctl_int_arr(ipcompctl_vars, name, namelen,
669 oldp, oldlenp, newp, newlen));
670 return (ENOPROTOOPT);
671 }
672
673 #ifdef INET
674
675 void
676 ah4_input(struct mbuf *m, ...)
677 {
678 int skip;
679
680 va_list ap;
681 va_start(ap, m);
682 skip = va_arg(ap, int);
683 va_end(ap);
684
685 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
686 IPPROTO_AH, 0);
687 return;
688 }
689
690
691 int
692 ah4_input_cb(struct mbuf *m, ...)
693 {
694 struct ifqueue *ifq = &ipintrq;
695 int s = splnet();
696
697
698
699
700
701
702 if (IF_QFULL(ifq)) {
703 IF_DROP(ifq);
704 ahstat.ahs_qfull++;
705 splx(s);
706
707 m_freem(m);
708 DPRINTF(("ah4_input_cb(): dropped packet because of full "
709 "IP queue\n"));
710 return ENOBUFS;
711 }
712
713 IF_ENQUEUE(ifq, m);
714 schednetisr(NETISR_IP);
715 splx(s);
716 return 0;
717 }
718
719
720 void *
721 ah4_ctlinput(int cmd, struct sockaddr *sa, void *v)
722 {
723 if (sa->sa_family != AF_INET ||
724 sa->sa_len != sizeof(struct sockaddr_in))
725 return (NULL);
726
727 return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_AH));
728 }
729
730
731 void
732 esp4_input(struct mbuf *m, ...)
733 {
734 int skip;
735
736 va_list ap;
737 va_start(ap, m);
738 skip = va_arg(ap, int);
739 va_end(ap);
740
741 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
742 IPPROTO_ESP, 0);
743 }
744
745
746 int
747 esp4_input_cb(struct mbuf *m, ...)
748 {
749 struct ifqueue *ifq = &ipintrq;
750 int s = splnet();
751
752
753
754
755
756 if (IF_QFULL(ifq)) {
757 IF_DROP(ifq);
758 espstat.esps_qfull++;
759 splx(s);
760
761 m_freem(m);
762 DPRINTF(("esp4_input_cb(): dropped packet because of full "
763 "IP queue\n"));
764 return ENOBUFS;
765 }
766
767 IF_ENQUEUE(ifq, m);
768 schednetisr(NETISR_IP);
769 splx(s);
770 return 0;
771 }
772
773
774 void
775 ipcomp4_input(struct mbuf *m, ...)
776 {
777 int skip;
778 va_list ap;
779 va_start(ap, m);
780 skip = va_arg(ap, int);
781 va_end(ap);
782
783 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET,
784 IPPROTO_IPCOMP, 0);
785 }
786
787
788 int
789 ipcomp4_input_cb(struct mbuf *m, ...)
790 {
791 struct ifqueue *ifq = &ipintrq;
792 int s = splnet();
793
794
795
796
797
798 if (IF_QFULL(ifq)) {
799 IF_DROP(ifq);
800 ipcompstat.ipcomps_qfull++;
801 splx(s);
802
803 m_freem(m);
804 DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n"));
805 return ENOBUFS;
806 }
807
808 IF_ENQUEUE(ifq, m);
809 schednetisr(NETISR_IP);
810 splx(s);
811
812 return 0;
813 }
814
815 void *
816 ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
817 {
818 extern u_int ip_mtudisc_timeout;
819 struct ip *ip = v;
820 int s;
821
822 if (cmd == PRC_MSGSIZE && ip && ip_mtudisc && ip->ip_v == 4) {
823 struct tdb *tdbp;
824 struct sockaddr_in dst;
825 struct icmp *icp;
826 int hlen = ip->ip_hl << 2;
827 u_int32_t spi, mtu;
828 ssize_t adjust;
829
830
831 icp = (struct icmp *)((caddr_t) ip -
832 offsetof(struct icmp, icmp_ip));
833 mtu = ntohs(icp->icmp_nextmtu);
834
835
836
837
838
839 if (mtu < 296)
840 return (NULL);
841
842 bzero(&dst, sizeof(struct sockaddr_in));
843 dst.sin_family = AF_INET;
844 dst.sin_len = sizeof(struct sockaddr_in);
845 dst.sin_addr.s_addr = ip->ip_dst.s_addr;
846
847 bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t));
848
849 s = spltdb();
850 tdbp = gettdb(spi, (union sockaddr_union *)&dst, proto);
851 if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) {
852 splx(s);
853 return (NULL);
854 }
855
856
857 for (; tdbp; tdbp = tdbp->tdb_inext) {
858 if (tdbp->tdb_flags & TDBF_INVALID ||
859 (adjust = ipsec_hdrsz(tdbp)) == -1) {
860 splx(s);
861 return (NULL);
862 }
863
864 mtu -= adjust;
865
866
867 tdbp->tdb_mtu = mtu;
868 tdbp->tdb_mtutimeout = time_second +
869 ip_mtudisc_timeout;
870 DPRINTF(("ipsec_common_ctlinput: "
871 "spi %08x mtu %d adjust %d\n",
872 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu,
873 adjust));
874 }
875 splx(s);
876 return (NULL);
877 }
878 return (NULL);
879 }
880
881 void *
882 udpencap_ctlinput(int cmd, struct sockaddr *sa, void *v)
883 {
884 struct ip *ip = v;
885 struct tdb *tdbp;
886 struct icmp *icp;
887 u_int32_t mtu;
888 ssize_t adjust;
889 struct sockaddr_in dst, src;
890 union sockaddr_union *su_dst, *su_src;
891 int s;
892
893 icp = (struct icmp *)((caddr_t) ip - offsetof(struct icmp, icmp_ip));
894 mtu = ntohs(icp->icmp_nextmtu);
895
896
897
898
899
900 if (mtu < 296)
901 return (NULL);
902
903 bzero(&dst, sizeof(dst));
904 dst.sin_family = AF_INET;
905 dst.sin_len = sizeof(struct sockaddr_in);
906 dst.sin_addr.s_addr = ip->ip_dst.s_addr;
907 su_dst = (union sockaddr_union *)&dst;
908 bzero(&src, sizeof(src));
909 src.sin_family = AF_INET;
910 src.sin_len = sizeof(struct sockaddr_in);
911 src.sin_addr.s_addr = ip->ip_src.s_addr;
912 su_src = (union sockaddr_union *)&src;
913
914 s = spltdb();
915 tdbp = gettdbbysrcdst(0, su_src, su_dst, IPPROTO_ESP);
916
917 for (; tdbp != NULL; tdbp = tdbp->tdb_snext) {
918 if (tdbp->tdb_sproto == IPPROTO_ESP &&
919 ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_UDPENCAP))
920 == TDBF_UDPENCAP) &&
921 !bcmp(&tdbp->tdb_dst, &dst, SA_LEN(&su_dst->sa)) &&
922 !bcmp(&tdbp->tdb_src, &src, SA_LEN(&su_src->sa))) {
923 if ((adjust = ipsec_hdrsz(tdbp)) != -1) {
924
925 tdbp->tdb_mtu = mtu - adjust;
926 tdbp->tdb_mtutimeout = time_second +
927 ip_mtudisc_timeout;
928 DPRINTF(("udpencap_ctlinput: "
929 "spi %08x mtu %d adjust %d\n",
930 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu,
931 adjust));
932 }
933 }
934 }
935 splx(s);
936 return (NULL);
937 }
938
939 void *
940 esp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
941 {
942 if (sa->sa_family != AF_INET ||
943 sa->sa_len != sizeof(struct sockaddr_in))
944 return (NULL);
945
946 return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_ESP));
947 }
948 #endif
949
950 #ifdef INET6
951
952 int
953 ah6_input(struct mbuf **mp, int *offp, int proto)
954 {
955 int l = 0;
956 int protoff, nxt;
957 struct ip6_ext ip6e;
958
959 if (*offp < sizeof(struct ip6_hdr)) {
960 DPRINTF(("ah6_input(): bad offset\n"));
961 return IPPROTO_DONE;
962 } else if (*offp == sizeof(struct ip6_hdr)) {
963 protoff = offsetof(struct ip6_hdr, ip6_nxt);
964 } else {
965
966 protoff = sizeof(struct ip6_hdr);
967 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
968
969 do {
970 protoff += l;
971 m_copydata(*mp, protoff, sizeof(ip6e),
972 (caddr_t) &ip6e);
973
974 if (nxt == IPPROTO_AH)
975 l = (ip6e.ip6e_len + 2) << 2;
976 else
977 l = (ip6e.ip6e_len + 1) << 3;
978 #ifdef DIAGNOSTIC
979 if (l <= 0)
980 panic("ah6_input: l went zero or negative");
981 #endif
982
983 nxt = ip6e.ip6e_nxt;
984 } while (protoff + l < *offp);
985
986
987 if (protoff + l != *offp) {
988 DPRINTF(("ah6_input(): bad packet header chain\n"));
989 ahstat.ahs_hdrops++;
990 m_freem(*mp);
991 *mp = NULL;
992 return IPPROTO_DONE;
993 }
994 protoff += offsetof(struct ip6_ext, ip6e_nxt);
995 }
996 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0);
997 return IPPROTO_DONE;
998 }
999
1000
1001 int
1002 ah6_input_cb(struct mbuf *m, int off, int protoff)
1003 {
1004 int nxt;
1005 u_int8_t nxt8;
1006 int nest = 0;
1007
1008
1009 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
1010 nxt = nxt8;
1011
1012
1013
1014
1015
1016 while (nxt != IPPROTO_DONE) {
1017 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
1018 ip6stat.ip6s_toomanyhdr++;
1019 goto bad;
1020 }
1021
1022
1023
1024
1025
1026 if (m->m_pkthdr.len < off) {
1027 ip6stat.ip6s_tooshort++;
1028 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
1029 goto bad;
1030 }
1031 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
1032 }
1033 return 0;
1034
1035 bad:
1036 m_freem(m);
1037 return EINVAL;
1038 }
1039
1040
1041 int
1042 esp6_input(struct mbuf **mp, int *offp, int proto)
1043 {
1044 int l = 0;
1045 int protoff, nxt;
1046 struct ip6_ext ip6e;
1047
1048 if (*offp < sizeof(struct ip6_hdr)) {
1049 DPRINTF(("esp6_input(): bad offset\n"));
1050 return IPPROTO_DONE;
1051 } else if (*offp == sizeof(struct ip6_hdr)) {
1052 protoff = offsetof(struct ip6_hdr, ip6_nxt);
1053 } else {
1054
1055 protoff = sizeof(struct ip6_hdr);
1056 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
1057
1058 do {
1059 protoff += l;
1060 m_copydata(*mp, protoff, sizeof(ip6e),
1061 (caddr_t) &ip6e);
1062
1063 if (nxt == IPPROTO_AH)
1064 l = (ip6e.ip6e_len + 2) << 2;
1065 else
1066 l = (ip6e.ip6e_len + 1) << 3;
1067 #ifdef DIAGNOSTIC
1068 if (l <= 0)
1069 panic("esp6_input: l went zero or negative");
1070 #endif
1071
1072 nxt = ip6e.ip6e_nxt;
1073 } while (protoff + l < *offp);
1074
1075
1076 if (protoff + l != *offp) {
1077 DPRINTF(("esp6_input(): bad packet header chain\n"));
1078 espstat.esps_hdrops++;
1079 m_freem(*mp);
1080 *mp = NULL;
1081 return IPPROTO_DONE;
1082 }
1083 protoff += offsetof(struct ip6_ext, ip6e_nxt);
1084 }
1085 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0);
1086 return IPPROTO_DONE;
1087
1088 }
1089
1090
1091 int
1092 esp6_input_cb(struct mbuf *m, int skip, int protoff)
1093 {
1094 return ah6_input_cb(m, skip, protoff);
1095 }
1096
1097
1098 int
1099 ipcomp6_input(struct mbuf **mp, int *offp, int proto)
1100 {
1101 int l = 0;
1102 int protoff, nxt;
1103 struct ip6_ext ip6e;
1104
1105 if (*offp < sizeof(struct ip6_hdr)) {
1106 DPRINTF(("ipcomp6_input(): bad offset\n"));
1107 return IPPROTO_DONE;
1108 } else if (*offp == sizeof(struct ip6_hdr)) {
1109 protoff = offsetof(struct ip6_hdr, ip6_nxt);
1110 } else {
1111
1112 protoff = sizeof(struct ip6_hdr);
1113 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
1114
1115 do {
1116 protoff += l;
1117 m_copydata(*mp, protoff, sizeof(ip6e),
1118 (caddr_t) &ip6e);
1119 if (nxt == IPPROTO_AH)
1120 l = (ip6e.ip6e_len + 2) << 2;
1121 else
1122 l = (ip6e.ip6e_len + 1) << 3;
1123 #ifdef DIAGNOSTIC
1124 if (l <= 0)
1125 panic("ipcomp6_input: l went zero or negative");
1126 #endif
1127
1128 nxt = ip6e.ip6e_nxt;
1129 } while (protoff + l < *offp);
1130
1131
1132 if (protoff + l != *offp) {
1133 DPRINTF(("ipcomp6_input(): bad packet header chain\n"));
1134 ipcompstat.ipcomps_hdrops++;
1135 m_freem(*mp);
1136 *mp = NULL;
1137 return IPPROTO_DONE;
1138 }
1139
1140 protoff += offsetof(struct ip6_ext, ip6e_nxt);
1141 }
1142 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0);
1143 return IPPROTO_DONE;
1144 }
1145
1146
1147 int
1148 ipcomp6_input_cb(struct mbuf *m, int skip, int protoff)
1149 {
1150 return ah6_input_cb(m, skip, protoff);
1151 }
1152
1153 #endif