2 /* $KAME: esp_input.c,v 1.55 2001/03/23 08:08:47 itojun Exp $ */
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * RFC1827/2406 Encapsulated Security Payload.
38 #include "opt_inet6.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <sys/domain.h>
44 #include <sys/protosw.h>
45 #include <sys/socket.h>
46 #include <sys/errno.h>
48 #include <sys/syslog.h>
51 #include <net/route.h>
52 #include <net/netisr.h>
53 #include <machine/cpu.h>
55 #include <netinet/in.h>
56 #include <netinet/in_systm.h>
57 #include <netinet/ip.h>
58 #include <netinet/ip_var.h>
59 #include <netinet/in_var.h>
60 #include <netinet/ip_ecn.h>
62 #include <netinet6/ip6_ecn.h>
66 #include <netinet/ip6.h>
67 #include <netinet6/in6_pcb.h>
68 #include <netinet6/ip6_var.h>
69 #include <netinet/icmp6.h>
70 #include <netinet6/ip6protosw.h>
73 #include <netinet6/ipsec.h>
75 #include <netinet6/ipsec6.h>
77 #include <netinet6/ah.h>
79 #include <netinet6/ah6.h>
81 #include <netinet6/esp.h>
83 #include <netinet6/esp6.h>
85 #include <netkey/key.h>
86 #include <netkey/keydb.h>
87 #include <netkey/key_debug.h>
89 #include <machine/stdarg.h>
91 #include <net/net_osdep.h>
96 (sizeof(struct esp) < sizeof(struct newesp) \
97 ? sizeof(struct newesp) : sizeof(struct esp))
100 #include <netinet/ipprotosw.h>
101 extern struct ipprotosw inetsw[];
105 esp4_input(struct mbuf *m, ...)
107 esp4_input(m, va_alist)
114 struct esptail esptail;
116 struct secasvar *sav = NULL;
119 const struct esp_algorithm *algo;
127 off = va_arg(ap, int);
128 proto = va_arg(ap, int);
131 /* sanity check for alignment. */
132 if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
133 ipseclog((LOG_ERR, "IPv4 ESP input: packet alignment problem "
134 "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
135 ipsecstat.in_inval++;
139 if (m->m_len < off + ESPMAXLEN) {
140 m = m_pullup(m, off + ESPMAXLEN);
143 "IPv4 ESP input: can't pullup in esp4_input\n"));
144 ipsecstat.in_inval++;
149 ip = mtod(m, struct ip *);
150 esp = (struct esp *)(((u_int8_t *)ip) + off);
152 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
154 hlen = ip->ip_hl << 2;
157 /* find the sassoc. */
160 if ((sav = key_allocsa(AF_INET,
161 (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst,
162 IPPROTO_ESP, spi)) == 0) {
163 ipseclog((LOG_WARNING,
164 "IPv4 ESP input: no key association found for spi %u\n",
165 (u_int32_t)ntohl(spi)));
169 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
170 printf("DP esp4_input called to allocate SA:%p\n", sav));
171 if (sav->state != SADB_SASTATE_MATURE
172 && sav->state != SADB_SASTATE_DYING) {
174 "IPv4 ESP input: non-mature/dying SA found for spi %u\n",
175 (u_int32_t)ntohl(spi)));
176 ipsecstat.in_badspi++;
179 algo = esp_algorithm_lookup(sav->alg_enc);
181 ipseclog((LOG_DEBUG, "IPv4 ESP input: "
182 "unsupported encryption algorithm for spi %u\n",
183 (u_int32_t)ntohl(spi)));
184 ipsecstat.in_badspi++;
188 /* check if we have proper ivlen information */
191 ipseclog((LOG_ERR, "inproper ivlen in IPv4 ESP input: %s %s\n",
192 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
193 ipsecstat.in_inval++;
197 if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
198 && (sav->alg_auth && sav->key_auth)))
201 if (sav->alg_auth == SADB_X_AALG_NULL ||
202 sav->alg_auth == SADB_AALG_NONE)
206 * check for sequence number.
208 if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
211 ipsecstat.in_espreplay++;
212 ipseclog((LOG_WARNING,
213 "replay packet in IPv4 ESP input: %s %s\n",
214 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
220 u_char sum0[AH_MAXSUMSIZE];
221 u_char sum[AH_MAXSUMSIZE];
222 const struct ah_algorithm *sumalgo;
225 sumalgo = ah_algorithm_lookup(sav->alg_auth);
228 siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
229 if (AH_MAXSUMSIZE < siz) {
231 "internal error: AH_MAXSUMSIZE must be larger than %lu\n",
233 ipsecstat.in_inval++;
237 m_copydata(m, m->m_pkthdr.len - siz, siz, &sum0[0]);
239 if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
240 ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
241 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
242 ipsecstat.in_espauthfail++;
246 if (bcmp(sum0, sum, siz) != 0) {
247 ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
248 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
249 ipsecstat.in_espauthfail++;
253 /* strip off the authentication data */
255 ip = mtod(m, struct ip *);
257 ip->ip_len = ip->ip_len - siz;
259 ip->ip_len = htons(ntohs(ip->ip_len) - siz);
261 m->m_flags |= M_AUTHIPDGM;
262 ipsecstat.in_espauthsucc++;
266 * update sequence number.
268 if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
269 if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) {
270 ipsecstat.in_espreplay++;
277 /* process main esp header. */
278 if (sav->flags & SADB_X_EXT_OLD) {
280 esplen = sizeof(struct esp);
283 if (sav->flags & SADB_X_EXT_DERIV)
284 esplen = sizeof(struct esp);
286 esplen = sizeof(struct newesp);
289 if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
290 ipseclog((LOG_WARNING,
291 "IPv4 ESP input: packet too short\n"));
292 ipsecstat.in_inval++;
296 if (m->m_len < off + esplen + ivlen) {
297 m = m_pullup(m, off + esplen + ivlen);
300 "IPv4 ESP input: can't pullup in esp4_input\n"));
301 ipsecstat.in_inval++;
307 * pre-compute and cache intermediate key
309 if (esp_schedule(algo, sav) != 0) {
310 ipsecstat.in_inval++;
315 * decrypt the packet.
318 panic("internal error: no decrypt function");
319 if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
320 /* m is already freed */
322 ipseclog((LOG_ERR, "decrypt fail in IPv4 ESP input: %s\n",
323 ipsec_logsastr(sav)));
324 ipsecstat.in_inval++;
327 ipsecstat.in_esphist[sav->alg_enc]++;
329 m->m_flags |= M_DECRYPTED;
332 * find the trailer of the ESP.
334 m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
336 nxt = esptail.esp_nxt;
337 taillen = esptail.esp_padlen + sizeof(esptail);
339 if (m->m_pkthdr.len < taillen
340 || m->m_pkthdr.len - taillen < hlen) { /*?*/
341 ipseclog((LOG_WARNING,
342 "bad pad length in IPv4 ESP input: %s %s\n",
343 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
344 ipsecstat.in_inval++;
348 /* strip off the trailing pad area. */
352 ip->ip_len = ip->ip_len - taillen;
354 ip->ip_len = htons(ntohs(ip->ip_len) - taillen);
357 /* was it transmitted over the IPsec tunnel SA? */
358 if (ipsec4_tunnel_validate(m, off + esplen + ivlen, nxt, sav)) {
360 * strip off all the headers that precedes ESP header.
361 * IP4 xx ESP IP4' payload -> IP4' payload
363 * XXX more sanity checks
364 * XXX relationship with gif?
369 m_adj(m, off + esplen + ivlen);
370 if (m->m_len < sizeof(*ip)) {
371 m = m_pullup(m, sizeof(*ip));
373 ipsecstat.in_inval++;
377 ip = mtod(m, struct ip *);
378 /* ECN consideration. */
379 ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos);
380 if (!key_checktunnelsanity(sav, AF_INET,
381 (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
382 ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
383 "in IPv4 ESP input: %s %s\n",
384 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
385 ipsecstat.in_inval++;
389 #if 0 /* XXX should call ipfw rather than ipsec_in_reject, shouldn't it ? */
390 /* drop it if it does not match the default policy */
391 if (ipsec4_in_reject(m, NULL)) {
392 ipsecstat.in_polvio++;
397 key_sa_recordxfer(sav, m);
398 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 ||
399 ipsec_addhist(m, IPPROTO_IPV4, 0) != 0) {
400 ipsecstat.in_nomem++;
404 if (! IF_HANDOFF(&ipintrq, m, NULL)) {
405 ipsecstat.in_inval++;
410 schednetisr(NETISR_IP); /*can be skipped but to make sure*/
414 * strip off ESP header and IV.
415 * even in m_pulldown case, we need to strip off ESP so that
416 * we can always compute checksum for AH correctly.
420 stripsiz = esplen + ivlen;
422 ip = mtod(m, struct ip *);
423 ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), off);
424 m->m_data += stripsiz;
425 m->m_len -= stripsiz;
426 m->m_pkthdr.len -= stripsiz;
428 ip = mtod(m, struct ip *);
430 ip->ip_len = ip->ip_len - stripsiz;
432 ip->ip_len = htons(ntohs(ip->ip_len) - stripsiz);
436 key_sa_recordxfer(sav, m);
437 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) {
438 ipsecstat.in_nomem++;
442 if (nxt != IPPROTO_DONE) {
443 if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
444 ipsec4_in_reject(m, NULL)) {
445 ipsecstat.in_polvio++;
448 (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt);
455 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
456 printf("DP esp4_input call free SA:%p\n", sav));
459 ipsecstat.in_success++;
464 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
465 printf("DP esp4_input call free SA:%p\n", sav));
476 esp6_input(mp, offp, proto)
480 struct mbuf *m = *mp;
484 struct esptail esptail;
486 struct secasvar *sav = NULL;
489 const struct esp_algorithm *algo;
493 /* sanity check for alignment. */
494 if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
495 ipseclog((LOG_ERR, "IPv6 ESP input: packet alignment problem "
496 "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
497 ipsec6stat.in_inval++;
501 #ifndef PULLDOWN_TEST
502 IP6_EXTHDR_CHECK(m, off, ESPMAXLEN, IPPROTO_DONE);
503 esp = (struct esp *)(mtod(m, caddr_t) + off);
505 IP6_EXTHDR_GET(esp, struct esp *, m, off, ESPMAXLEN);
507 ipsec6stat.in_inval++;
511 ip6 = mtod(m, struct ip6_hdr *);
513 if (ntohs(ip6->ip6_plen) == 0) {
514 ipseclog((LOG_ERR, "IPv6 ESP input: "
515 "ESP with IPv6 jumbogram is not supported.\n"));
516 ipsec6stat.in_inval++;
520 /* find the sassoc. */
523 if ((sav = key_allocsa(AF_INET6,
524 (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst,
525 IPPROTO_ESP, spi)) == 0) {
526 ipseclog((LOG_WARNING,
527 "IPv6 ESP input: no key association found for spi %u\n",
528 (u_int32_t)ntohl(spi)));
529 ipsec6stat.in_nosa++;
532 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
533 printf("DP esp6_input called to allocate SA:%p\n", sav));
534 if (sav->state != SADB_SASTATE_MATURE
535 && sav->state != SADB_SASTATE_DYING) {
537 "IPv6 ESP input: non-mature/dying SA found for spi %u\n",
538 (u_int32_t)ntohl(spi)));
539 ipsec6stat.in_badspi++;
542 algo = esp_algorithm_lookup(sav->alg_enc);
544 ipseclog((LOG_DEBUG, "IPv6 ESP input: "
545 "unsupported encryption algorithm for spi %u\n",
546 (u_int32_t)ntohl(spi)));
547 ipsec6stat.in_badspi++;
551 /* check if we have proper ivlen information */
554 ipseclog((LOG_ERR, "inproper ivlen in IPv6 ESP input: %s %s\n",
555 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
556 ipsec6stat.in_badspi++;
560 if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
561 && (sav->alg_auth && sav->key_auth)))
564 if (sav->alg_auth == SADB_X_AALG_NULL ||
565 sav->alg_auth == SADB_AALG_NONE)
569 * check for sequence number.
571 if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
574 ipsec6stat.in_espreplay++;
575 ipseclog((LOG_WARNING,
576 "replay packet in IPv6 ESP input: %s %s\n",
577 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
583 u_char sum0[AH_MAXSUMSIZE];
584 u_char sum[AH_MAXSUMSIZE];
585 const struct ah_algorithm *sumalgo;
588 sumalgo = ah_algorithm_lookup(sav->alg_auth);
591 siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
592 if (AH_MAXSUMSIZE < siz) {
594 "internal error: AH_MAXSUMSIZE must be larger than %lu\n",
596 ipsec6stat.in_inval++;
600 m_copydata(m, m->m_pkthdr.len - siz, siz, &sum0[0]);
602 if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
603 ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
604 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
605 ipsec6stat.in_espauthfail++;
609 if (bcmp(sum0, sum, siz) != 0) {
610 ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
611 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
612 ipsec6stat.in_espauthfail++;
616 /* strip off the authentication data */
618 ip6 = mtod(m, struct ip6_hdr *);
619 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - siz);
621 m->m_flags |= M_AUTHIPDGM;
622 ipsec6stat.in_espauthsucc++;
626 * update sequence number.
628 if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
629 if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) {
630 ipsec6stat.in_espreplay++;
637 /* process main esp header. */
638 if (sav->flags & SADB_X_EXT_OLD) {
640 esplen = sizeof(struct esp);
643 if (sav->flags & SADB_X_EXT_DERIV)
644 esplen = sizeof(struct esp);
646 esplen = sizeof(struct newesp);
649 if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
650 ipseclog((LOG_WARNING,
651 "IPv6 ESP input: packet too short\n"));
652 ipsec6stat.in_inval++;
656 #ifndef PULLDOWN_TEST
657 IP6_EXTHDR_CHECK(m, off, esplen + ivlen, IPPROTO_DONE); /*XXX*/
659 IP6_EXTHDR_GET(esp, struct esp *, m, off, esplen + ivlen);
661 ipsec6stat.in_inval++;
666 ip6 = mtod(m, struct ip6_hdr *); /*set it again just in case*/
669 * pre-compute and cache intermediate key
671 if (esp_schedule(algo, sav) != 0) {
672 ipsec6stat.in_inval++;
677 * decrypt the packet.
680 panic("internal error: no decrypt function");
681 if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
682 /* m is already freed */
684 ipseclog((LOG_ERR, "decrypt fail in IPv6 ESP input: %s\n",
685 ipsec_logsastr(sav)));
686 ipsec6stat.in_inval++;
689 ipsec6stat.in_esphist[sav->alg_enc]++;
691 m->m_flags |= M_DECRYPTED;
694 * find the trailer of the ESP.
696 m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
698 nxt = esptail.esp_nxt;
699 taillen = esptail.esp_padlen + sizeof(esptail);
701 if (m->m_pkthdr.len < taillen
702 || m->m_pkthdr.len - taillen < sizeof(struct ip6_hdr)) { /*?*/
703 ipseclog((LOG_WARNING,
704 "bad pad length in IPv6 ESP input: %s %s\n",
705 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
706 ipsec6stat.in_inval++;
710 /* strip off the trailing pad area. */
713 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - taillen);
715 /* was it transmitted over the IPsec tunnel SA? */
716 if (ipsec6_tunnel_validate(m, off + esplen + ivlen, nxt, sav)) {
718 * strip off all the headers that precedes ESP header.
719 * IP6 xx ESP IP6' payload -> IP6' payload
721 * XXX more sanity checks
722 * XXX relationship with gif?
724 u_int32_t flowinfo; /*net endian*/
725 flowinfo = ip6->ip6_flow;
726 m_adj(m, off + esplen + ivlen);
727 if (m->m_len < sizeof(*ip6)) {
728 #ifndef PULLDOWN_TEST
730 * m_pullup is prohibited in KAME IPv6 input processing
731 * but there's no other way!
734 /* okay to pullup in m_pulldown style */
736 m = m_pullup(m, sizeof(*ip6));
738 ipsec6stat.in_inval++;
742 ip6 = mtod(m, struct ip6_hdr *);
743 /* ECN consideration. */
744 ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow);
745 if (!key_checktunnelsanity(sav, AF_INET6,
746 (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
747 ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
748 "in IPv6 ESP input: %s %s\n",
749 ipsec6_logpacketstr(ip6, spi),
750 ipsec_logsastr(sav)));
751 ipsec6stat.in_inval++;
755 #if 0 /* XXX should call ipfw rather than ipsec_in_reject, shouldn't it ? */
756 /* drop it if it does not match the default policy */
757 if (ipsec6_in_reject(m, NULL)) {
758 ipsec6stat.in_polvio++;
763 key_sa_recordxfer(sav, m);
764 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 ||
765 ipsec_addhist(m, IPPROTO_IPV6, 0) != 0) {
766 ipsec6stat.in_nomem++;
770 if (! IF_HANDOFF(&ip6intrq, m, NULL)) {
771 ipsec6stat.in_inval++;
776 schednetisr(NETISR_IPV6); /*can be skipped but to make sure*/
780 * strip off ESP header and IV.
781 * even in m_pulldown case, we need to strip off ESP so that
782 * we can always compute checksum for AH correctly.
788 * Set the next header field of the previous header correctly.
790 prvnxtp = ip6_get_prevhdr(m, off); /* XXX */
793 stripsiz = esplen + ivlen;
795 ip6 = mtod(m, struct ip6_hdr *);
796 if (m->m_len >= stripsiz + off) {
797 ovbcopy((caddr_t)ip6, ((caddr_t)ip6) + stripsiz, off);
798 m->m_data += stripsiz;
799 m->m_len -= stripsiz;
800 m->m_pkthdr.len -= stripsiz;
803 * this comes with no copy if the boundary is on
808 n = m_split(m, off, M_DONTWAIT);
810 /* m is retained by m_split */
815 /* m_cat does not update m_pkthdr.len */
816 m->m_pkthdr.len += n->m_pkthdr.len;
819 #ifndef PULLDOWN_TEST
821 * KAME requires that the packet to be contiguous on the
822 * mbuf. We need to make that sure.
823 * this kind of code should be avoided.
824 * XXX other conditions to avoid running this part?
826 if (m->m_len != m->m_pkthdr.len) {
827 struct mbuf *n = NULL;
830 MGETHDR(n, M_DONTWAIT, MT_HEADER);
834 if (n && m->m_pkthdr.len > maxlen) {
835 MCLGET(n, M_DONTWAIT);
837 if ((n->m_flags & M_EXT) == 0) {
843 printf("esp6_input: mbuf allocation failed\n");
847 if (m->m_pkthdr.len <= maxlen) {
848 m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
849 n->m_len = m->m_pkthdr.len;
850 n->m_pkthdr.len = m->m_pkthdr.len;
854 m_copydata(m, 0, maxlen, mtod(n, caddr_t));
857 n->m_pkthdr.len = m->m_pkthdr.len;
859 m->m_flags &= ~M_PKTHDR;
865 ip6 = mtod(m, struct ip6_hdr *);
866 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
868 key_sa_recordxfer(sav, m);
869 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) {
870 ipsec6stat.in_nomem++;
879 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
880 printf("DP esp6_input call free SA:%p\n", sav));
883 ipsec6stat.in_success++;
888 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
889 printf("DP esp6_input call free SA:%p\n", sav));
898 esp6_ctlinput(cmd, sa, d)
903 const struct newesp *espp;
905 struct ip6ctlparam *ip6cp = NULL, ip6cp1;
906 struct secasvar *sav;
910 struct sockaddr_in6 sa6_src, sa6_dst;
912 if (sa->sa_family != AF_INET6 ||
913 sa->sa_len != sizeof(struct sockaddr_in6))
915 if ((unsigned)cmd >= PRC_NCMDS)
918 /* if the parameter is from icmp6, decode it. */
920 ip6cp = (struct ip6ctlparam *)d;
922 ip6 = ip6cp->ip6c_ip6;
923 off = ip6cp->ip6c_off;
931 * Notify the error to all possible sockets via pfctlinput2.
932 * Since the upper layer information (such as protocol type,
933 * source and destination ports) is embedded in the encrypted
934 * data and might have been cut, we can't directly call
935 * an upper layer ctlinput function. However, the pcbnotify
936 * function will consider source and destination addresses
937 * as well as the flow info value, and may be able to find
938 * some PCB that should be notified.
939 * Although pfctlinput2 will call esp6_ctlinput(), there is
940 * no possibility of an infinite loop of function calls,
941 * because we don't pass the inner IPv6 header.
943 bzero(&ip6cp1, sizeof(ip6cp1));
944 ip6cp1.ip6c_src = ip6cp->ip6c_src;
945 pfctlinput2(cmd, sa, (void *)&ip6cp1);
948 * Then go to special cases that need ESP header information.
949 * XXX: We assume that when ip6 is non NULL,
950 * M and OFF are valid.
953 /* check if we can safely examine src and dst ports */
954 if (m->m_pkthdr.len < off + sizeof(esp))
957 if (m->m_len < off + sizeof(esp)) {
959 * this should be rare case,
960 * so we compromise on this copy...
962 m_copydata(m, off, sizeof(esp), (caddr_t)&esp);
965 espp = (struct newesp*)(mtod(m, caddr_t) + off);
967 if (cmd == PRC_MSGSIZE) {
971 * Check to see if we have a valid SA corresponding to
972 * the address in the ICMP message payload.
974 sav = key_allocsa(AF_INET6,
975 (caddr_t)&sa6_src.sin6_addr,
976 (caddr_t)&sa6_dst, IPPROTO_ESP,
979 if (sav->state == SADB_SASTATE_MATURE ||
980 sav->state == SADB_SASTATE_DYING)
985 /* XXX Further validation? */
988 * Depending on the value of "valid" and routing table
989 * size (mtudisc_{hi,lo}wat), we will:
990 * - recalcurate the new MTU and create the
991 * corresponding routing entry, or
992 * - ignore the MTU change notification.
994 icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
997 /* we normally notify any pcb here */