1 /* $FreeBSD: src/sys/netinet6/esp_input.c,v 1.1.2.8 2003/01/23 21:06:47 sam Exp $ */
2 /* $DragonFly: src/sys/netinet6/esp_input.c,v 1.2 2003/06/17 04:28:51 dillon Exp $ */
3 /* $KAME: esp_input.c,v 1.62 2002/01/07 11:39:57 kjc Exp $ */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * RFC1827/2406 Encapsulated Security Payload.
39 #include "opt_inet6.h"
41 #include <sys/param.h>
42 #include <sys/systm.h>
44 #include <sys/domain.h>
45 #include <sys/protosw.h>
46 #include <sys/socket.h>
47 #include <sys/errno.h>
49 #include <sys/syslog.h>
52 #include <net/route.h>
53 #include <net/netisr.h>
54 #include <machine/cpu.h>
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_ecn.h>
63 #include <netinet6/ip6_ecn.h>
67 #include <netinet/ip6.h>
68 #include <netinet6/in6_pcb.h>
69 #include <netinet6/ip6_var.h>
70 #include <netinet/icmp6.h>
71 #include <netinet6/ip6protosw.h>
74 #include <netinet6/ipsec.h>
76 #include <netinet6/ipsec6.h>
78 #include <netinet6/ah.h>
80 #include <netinet6/ah6.h>
82 #include <netinet6/esp.h>
84 #include <netinet6/esp6.h>
86 #include <netkey/key.h>
87 #include <netkey/keydb.h>
88 #include <netkey/key_debug.h>
90 #include <machine/stdarg.h>
92 #include <net/net_osdep.h>
97 (sizeof(struct esp) < sizeof(struct newesp) \
98 ? sizeof(struct newesp) : sizeof(struct esp))
101 #include <netinet/ipprotosw.h>
102 extern struct ipprotosw inetsw[];
106 esp4_input(struct mbuf *m, ...)
108 esp4_input(m, va_alist)
115 struct esptail esptail;
117 struct secasvar *sav = NULL;
120 const struct esp_algorithm *algo;
129 off = va_arg(ap, int);
130 proto = va_arg(ap, int);
133 /* sanity check for alignment. */
134 if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
135 ipseclog((LOG_ERR, "IPv4 ESP input: packet alignment problem "
136 "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
137 ipsecstat.in_inval++;
141 if (m->m_len < off + ESPMAXLEN) {
142 m = m_pullup(m, off + ESPMAXLEN);
145 "IPv4 ESP input: can't pullup in esp4_input\n"));
146 ipsecstat.in_inval++;
151 ip = mtod(m, struct ip *);
152 esp = (struct esp *)(((u_int8_t *)ip) + off);
154 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
156 hlen = ip->ip_hl << 2;
159 /* find the sassoc. */
162 if ((sav = key_allocsa(AF_INET,
163 (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst,
164 IPPROTO_ESP, spi)) == 0) {
165 ipseclog((LOG_WARNING,
166 "IPv4 ESP input: no key association found for spi %u\n",
167 (u_int32_t)ntohl(spi)));
171 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
172 printf("DP esp4_input called to allocate SA:%p\n", sav));
173 if (sav->state != SADB_SASTATE_MATURE
174 && sav->state != SADB_SASTATE_DYING) {
176 "IPv4 ESP input: non-mature/dying SA found for spi %u\n",
177 (u_int32_t)ntohl(spi)));
178 ipsecstat.in_badspi++;
181 algo = esp_algorithm_lookup(sav->alg_enc);
183 ipseclog((LOG_DEBUG, "IPv4 ESP input: "
184 "unsupported encryption algorithm for spi %u\n",
185 (u_int32_t)ntohl(spi)));
186 ipsecstat.in_badspi++;
190 /* check if we have proper ivlen information */
193 ipseclog((LOG_ERR, "inproper ivlen in IPv4 ESP input: %s %s\n",
194 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
195 ipsecstat.in_inval++;
199 if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
200 && (sav->alg_auth && sav->key_auth)))
203 if (sav->alg_auth == SADB_X_AALG_NULL ||
204 sav->alg_auth == SADB_AALG_NONE)
208 * check for sequence number.
210 if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
213 ipsecstat.in_espreplay++;
214 ipseclog((LOG_WARNING,
215 "replay packet in IPv4 ESP input: %s %s\n",
216 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
222 u_char sum0[AH_MAXSUMSIZE];
223 u_char sum[AH_MAXSUMSIZE];
224 const struct ah_algorithm *sumalgo;
227 sumalgo = ah_algorithm_lookup(sav->alg_auth);
230 siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
231 if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
232 ipsecstat.in_inval++;
235 if (AH_MAXSUMSIZE < siz) {
237 "internal error: AH_MAXSUMSIZE must be larger than %lu\n",
239 ipsecstat.in_inval++;
243 m_copydata(m, m->m_pkthdr.len - siz, siz, &sum0[0]);
245 if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
246 ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
247 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
248 ipsecstat.in_espauthfail++;
252 if (bcmp(sum0, sum, siz) != 0) {
253 ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
254 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
255 ipsecstat.in_espauthfail++;
259 /* strip off the authentication data */
261 ip = mtod(m, struct ip *);
263 ip->ip_len = ip->ip_len - siz;
265 ip->ip_len = htons(ntohs(ip->ip_len) - siz);
267 m->m_flags |= M_AUTHIPDGM;
268 ipsecstat.in_espauthsucc++;
272 * update sequence number.
274 if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
275 if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) {
276 ipsecstat.in_espreplay++;
283 /* process main esp header. */
284 if (sav->flags & SADB_X_EXT_OLD) {
286 esplen = sizeof(struct esp);
289 if (sav->flags & SADB_X_EXT_DERIV)
290 esplen = sizeof(struct esp);
292 esplen = sizeof(struct newesp);
295 if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
296 ipseclog((LOG_WARNING,
297 "IPv4 ESP input: packet too short\n"));
298 ipsecstat.in_inval++;
302 if (m->m_len < off + esplen + ivlen) {
303 m = m_pullup(m, off + esplen + ivlen);
306 "IPv4 ESP input: can't pullup in esp4_input\n"));
307 ipsecstat.in_inval++;
313 * pre-compute and cache intermediate key
315 if (esp_schedule(algo, sav) != 0) {
316 ipsecstat.in_inval++;
321 * decrypt the packet.
324 panic("internal error: no decrypt function");
325 if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
326 /* m is already freed */
328 ipseclog((LOG_ERR, "decrypt fail in IPv4 ESP input: %s\n",
329 ipsec_logsastr(sav)));
330 ipsecstat.in_inval++;
333 ipsecstat.in_esphist[sav->alg_enc]++;
335 m->m_flags |= M_DECRYPTED;
338 * find the trailer of the ESP.
340 m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
342 nxt = esptail.esp_nxt;
343 taillen = esptail.esp_padlen + sizeof(esptail);
345 if (m->m_pkthdr.len < taillen
346 || m->m_pkthdr.len - taillen < hlen) { /* ? */
347 ipseclog((LOG_WARNING,
348 "bad pad length in IPv4 ESP input: %s %s\n",
349 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
350 ipsecstat.in_inval++;
354 /* strip off the trailing pad area. */
358 ip->ip_len = ip->ip_len - taillen;
360 ip->ip_len = htons(ntohs(ip->ip_len) - taillen);
363 /* was it transmitted over the IPsec tunnel SA? */
364 if (ipsec4_tunnel_validate(m, off + esplen + ivlen, nxt, sav)) {
366 * strip off all the headers that precedes ESP header.
367 * IP4 xx ESP IP4' payload -> IP4' payload
369 * XXX more sanity checks
370 * XXX relationship with gif?
375 m_adj(m, off + esplen + ivlen);
376 if (m->m_len < sizeof(*ip)) {
377 m = m_pullup(m, sizeof(*ip));
379 ipsecstat.in_inval++;
383 ip = mtod(m, struct ip *);
384 /* ECN consideration. */
385 ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos);
386 if (!key_checktunnelsanity(sav, AF_INET,
387 (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
388 ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
389 "in IPv4 ESP input: %s %s\n",
390 ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
391 ipsecstat.in_inval++;
395 key_sa_recordxfer(sav, m);
396 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 ||
397 ipsec_addhist(m, IPPROTO_IPV4, 0) != 0) {
398 ipsecstat.in_nomem++;
403 if (IF_QFULL(&ipintrq)) {
404 ipsecstat.in_inval++;
408 IF_ENQUEUE(&ipintrq, m);
410 schednetisr(NETISR_IP); /* can be skipped but to make sure */
415 * strip off ESP header and IV.
416 * even in m_pulldown case, we need to strip off ESP so that
417 * we can always compute checksum for AH correctly.
421 stripsiz = esplen + ivlen;
423 ip = mtod(m, struct ip *);
424 ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), off);
425 m->m_data += stripsiz;
426 m->m_len -= stripsiz;
427 m->m_pkthdr.len -= stripsiz;
429 ip = mtod(m, struct ip *);
431 ip->ip_len = ip->ip_len - stripsiz;
433 ip->ip_len = htons(ntohs(ip->ip_len) - stripsiz);
437 key_sa_recordxfer(sav, m);
438 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) {
439 ipsecstat.in_nomem++;
443 if (nxt != IPPROTO_DONE) {
444 if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
445 ipsec4_in_reject(m, NULL)) {
446 ipsecstat.in_polvio++;
449 (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt);
456 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
457 printf("DP esp4_input call free SA:%p\n", sav));
460 ipsecstat.in_success++;
465 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
466 printf("DP esp4_input call free SA:%p\n", sav));
477 esp6_input(mp, offp, proto)
481 struct mbuf *m = *mp;
485 struct esptail esptail;
487 struct secasvar *sav = NULL;
490 const struct esp_algorithm *algo;
495 /* sanity check for alignment. */
496 if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
497 ipseclog((LOG_ERR, "IPv6 ESP input: packet alignment problem "
498 "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
499 ipsec6stat.in_inval++;
503 #ifndef PULLDOWN_TEST
504 IP6_EXTHDR_CHECK(m, off, ESPMAXLEN, IPPROTO_DONE);
505 esp = (struct esp *)(mtod(m, caddr_t) + off);
507 IP6_EXTHDR_GET(esp, struct esp *, m, off, ESPMAXLEN);
509 ipsec6stat.in_inval++;
513 ip6 = mtod(m, struct ip6_hdr *);
515 if (ntohs(ip6->ip6_plen) == 0) {
516 ipseclog((LOG_ERR, "IPv6 ESP input: "
517 "ESP with IPv6 jumbogram is not supported.\n"));
518 ipsec6stat.in_inval++;
522 /* find the sassoc. */
525 if ((sav = key_allocsa(AF_INET6,
526 (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst,
527 IPPROTO_ESP, spi)) == 0) {
528 ipseclog((LOG_WARNING,
529 "IPv6 ESP input: no key association found for spi %u\n",
530 (u_int32_t)ntohl(spi)));
531 ipsec6stat.in_nosa++;
534 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
535 printf("DP esp6_input called to allocate SA:%p\n", sav));
536 if (sav->state != SADB_SASTATE_MATURE
537 && sav->state != SADB_SASTATE_DYING) {
539 "IPv6 ESP input: non-mature/dying SA found for spi %u\n",
540 (u_int32_t)ntohl(spi)));
541 ipsec6stat.in_badspi++;
544 algo = esp_algorithm_lookup(sav->alg_enc);
546 ipseclog((LOG_DEBUG, "IPv6 ESP input: "
547 "unsupported encryption algorithm for spi %u\n",
548 (u_int32_t)ntohl(spi)));
549 ipsec6stat.in_badspi++;
553 /* check if we have proper ivlen information */
556 ipseclog((LOG_ERR, "inproper ivlen in IPv6 ESP input: %s %s\n",
557 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
558 ipsec6stat.in_badspi++;
562 if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
563 && (sav->alg_auth && sav->key_auth)))
566 if (sav->alg_auth == SADB_X_AALG_NULL ||
567 sav->alg_auth == SADB_AALG_NONE)
571 * check for sequence number.
573 if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
576 ipsec6stat.in_espreplay++;
577 ipseclog((LOG_WARNING,
578 "replay packet in IPv6 ESP input: %s %s\n",
579 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
585 u_char sum0[AH_MAXSUMSIZE];
586 u_char sum[AH_MAXSUMSIZE];
587 const struct ah_algorithm *sumalgo;
590 sumalgo = ah_algorithm_lookup(sav->alg_auth);
593 siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
594 if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
595 ipsecstat.in_inval++;
598 if (AH_MAXSUMSIZE < siz) {
600 "internal error: AH_MAXSUMSIZE must be larger than %lu\n",
602 ipsec6stat.in_inval++;
606 m_copydata(m, m->m_pkthdr.len - siz, siz, &sum0[0]);
608 if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
609 ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
610 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
611 ipsec6stat.in_espauthfail++;
615 if (bcmp(sum0, sum, siz) != 0) {
616 ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
617 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
618 ipsec6stat.in_espauthfail++;
622 /* strip off the authentication data */
624 ip6 = mtod(m, struct ip6_hdr *);
625 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - siz);
627 m->m_flags |= M_AUTHIPDGM;
628 ipsec6stat.in_espauthsucc++;
632 * update sequence number.
634 if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
635 if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) {
636 ipsec6stat.in_espreplay++;
643 /* process main esp header. */
644 if (sav->flags & SADB_X_EXT_OLD) {
646 esplen = sizeof(struct esp);
649 if (sav->flags & SADB_X_EXT_DERIV)
650 esplen = sizeof(struct esp);
652 esplen = sizeof(struct newesp);
655 if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
656 ipseclog((LOG_WARNING,
657 "IPv6 ESP input: packet too short\n"));
658 ipsec6stat.in_inval++;
662 #ifndef PULLDOWN_TEST
663 IP6_EXTHDR_CHECK(m, off, esplen + ivlen, IPPROTO_DONE); /* XXX */
665 IP6_EXTHDR_GET(esp, struct esp *, m, off, esplen + ivlen);
667 ipsec6stat.in_inval++;
672 ip6 = mtod(m, struct ip6_hdr *); /* set it again just in case */
675 * pre-compute and cache intermediate key
677 if (esp_schedule(algo, sav) != 0) {
678 ipsec6stat.in_inval++;
683 * decrypt the packet.
686 panic("internal error: no decrypt function");
687 if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
688 /* m is already freed */
690 ipseclog((LOG_ERR, "decrypt fail in IPv6 ESP input: %s\n",
691 ipsec_logsastr(sav)));
692 ipsec6stat.in_inval++;
695 ipsec6stat.in_esphist[sav->alg_enc]++;
697 m->m_flags |= M_DECRYPTED;
700 * find the trailer of the ESP.
702 m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
704 nxt = esptail.esp_nxt;
705 taillen = esptail.esp_padlen + sizeof(esptail);
707 if (m->m_pkthdr.len < taillen
708 || m->m_pkthdr.len - taillen < sizeof(struct ip6_hdr)) { /* ? */
709 ipseclog((LOG_WARNING,
710 "bad pad length in IPv6 ESP input: %s %s\n",
711 ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
712 ipsec6stat.in_inval++;
716 /* strip off the trailing pad area. */
719 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - taillen);
721 /* was it transmitted over the IPsec tunnel SA? */
722 if (ipsec6_tunnel_validate(m, off + esplen + ivlen, nxt, sav)) {
724 * strip off all the headers that precedes ESP header.
725 * IP6 xx ESP IP6' payload -> IP6' payload
727 * XXX more sanity checks
728 * XXX relationship with gif?
730 u_int32_t flowinfo; /* net endian */
731 flowinfo = ip6->ip6_flow;
732 m_adj(m, off + esplen + ivlen);
733 if (m->m_len < sizeof(*ip6)) {
734 #ifndef PULLDOWN_TEST
736 * m_pullup is prohibited in KAME IPv6 input processing
737 * but there's no other way!
740 /* okay to pullup in m_pulldown style */
742 m = m_pullup(m, sizeof(*ip6));
744 ipsec6stat.in_inval++;
748 ip6 = mtod(m, struct ip6_hdr *);
749 /* ECN consideration. */
750 ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow);
751 if (!key_checktunnelsanity(sav, AF_INET6,
752 (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
753 ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
754 "in IPv6 ESP input: %s %s\n",
755 ipsec6_logpacketstr(ip6, spi),
756 ipsec_logsastr(sav)));
757 ipsec6stat.in_inval++;
761 key_sa_recordxfer(sav, m);
762 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 ||
763 ipsec_addhist(m, IPPROTO_IPV6, 0) != 0) {
764 ipsec6stat.in_nomem++;
769 if (IF_QFULL(&ip6intrq)) {
770 ipsec6stat.in_inval++;
774 IF_ENQUEUE(&ip6intrq, m);
776 schednetisr(NETISR_IPV6); /* can be skipped but to make sure */
781 * strip off ESP header and IV.
782 * even in m_pulldown case, we need to strip off ESP so that
783 * we can always compute checksum for AH correctly.
789 * Set the next header field of the previous header correctly.
791 prvnxtp = ip6_get_prevhdr(m, off); /* XXX */
794 stripsiz = esplen + ivlen;
796 ip6 = mtod(m, struct ip6_hdr *);
797 if (m->m_len >= stripsiz + off) {
798 ovbcopy((caddr_t)ip6, ((caddr_t)ip6) + stripsiz, off);
799 m->m_data += stripsiz;
800 m->m_len -= stripsiz;
801 m->m_pkthdr.len -= stripsiz;
804 * this comes with no copy if the boundary is on
809 n = m_split(m, off, M_DONTWAIT);
811 /* m is retained by m_split */
816 /* m_cat does not update m_pkthdr.len */
817 m->m_pkthdr.len += n->m_pkthdr.len;
820 #ifndef PULLDOWN_TEST
822 * KAME requires that the packet to be contiguous on the
823 * mbuf. We need to make that sure.
824 * this kind of code should be avoided.
825 * XXX other conditions to avoid running this part?
827 if (m->m_len != m->m_pkthdr.len) {
828 struct mbuf *n = NULL;
831 MGETHDR(n, M_DONTWAIT, MT_HEADER);
835 if (n && n->m_pkthdr.len > maxlen) {
836 MCLGET(n, M_DONTWAIT);
838 if ((n->m_flags & M_EXT) == 0) {
844 printf("esp6_input: mbuf allocation failed\n");
848 if (n->m_pkthdr.len <= maxlen) {
849 m_copydata(m, 0, n->m_pkthdr.len, mtod(n, caddr_t));
850 n->m_len = n->m_pkthdr.len;
854 m_copydata(m, 0, maxlen, mtod(n, caddr_t));
863 ip6 = mtod(m, struct ip6_hdr *);
864 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
866 key_sa_recordxfer(sav, m);
867 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) {
868 ipsec6stat.in_nomem++;
877 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
878 printf("DP esp6_input call free SA:%p\n", sav));
881 ipsec6stat.in_success++;
886 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
887 printf("DP esp6_input call free SA:%p\n", sav));
896 esp6_ctlinput(cmd, sa, d)
901 const struct newesp *espp;
903 struct ip6ctlparam *ip6cp = NULL, ip6cp1;
904 struct secasvar *sav;
908 struct sockaddr_in6 *sa6_src, *sa6_dst;
910 if (sa->sa_family != AF_INET6 ||
911 sa->sa_len != sizeof(struct sockaddr_in6))
913 if ((unsigned)cmd >= PRC_NCMDS)
916 /* if the parameter is from icmp6, decode it. */
918 ip6cp = (struct ip6ctlparam *)d;
920 ip6 = ip6cp->ip6c_ip6;
921 off = ip6cp->ip6c_off;
929 * Notify the error to all possible sockets via pfctlinput2.
930 * Since the upper layer information (such as protocol type,
931 * source and destination ports) is embedded in the encrypted
932 * data and might have been cut, we can't directly call
933 * an upper layer ctlinput function. However, the pcbnotify
934 * function will consider source and destination addresses
935 * as well as the flow info value, and may be able to find
936 * some PCB that should be notified.
937 * Although pfctlinput2 will call esp6_ctlinput(), there is
938 * no possibility of an infinite loop of function calls,
939 * because we don't pass the inner IPv6 header.
941 bzero(&ip6cp1, sizeof(ip6cp1));
942 ip6cp1.ip6c_src = ip6cp->ip6c_src;
943 pfctlinput2(cmd, sa, (void *)&ip6cp1);
946 * Then go to special cases that need ESP header information.
947 * XXX: We assume that when ip6 is non NULL,
948 * M and OFF are valid.
951 /* check if we can safely examine src and dst ports */
952 if (m->m_pkthdr.len < off + sizeof(esp))
955 if (m->m_len < off + sizeof(esp)) {
957 * this should be rare case,
958 * so we compromise on this copy...
960 m_copydata(m, off, sizeof(esp), (caddr_t)&esp);
963 espp = (struct newesp*)(mtod(m, caddr_t) + off);
965 if (cmd == PRC_MSGSIZE) {
969 * Check to see if we have a valid SA corresponding to
970 * the address in the ICMP message payload.
972 sa6_src = ip6cp->ip6c_src;
973 sa6_dst = (struct sockaddr_in6 *)sa;
974 sav = key_allocsa(AF_INET6,
975 (caddr_t)&sa6_src->sin6_addr,
976 (caddr_t)&sa6_dst->sin6_addr,
977 IPPROTO_ESP, espp->esp_spi);
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 */