ipsec_input.c revision 1.45 1 /* $NetBSD: ipsec_input.c,v 1.45 2017/07/05 03:44:59 ozaki-r Exp $ */
2 /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $ */
3 /* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */
4
5 /*
6 * The authors of this code are John Ioannidis (ji (at) tla.org),
7 * Angelos D. Keromytis (kermit (at) csd.uch.gr) and
8 * Niels Provos (provos (at) physnet.uni-hamburg.de).
9 *
10 * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
11 * in November 1995.
12 *
13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
14 * by Angelos D. Keromytis.
15 *
16 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
17 * and Niels Provos.
18 *
19 * Additional features in 1999 by Angelos D. Keromytis.
20 *
21 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
22 * Angelos D. Keromytis and Niels Provos.
23 * Copyright (c) 2001, Angelos D. Keromytis.
24 *
25 * Permission to use, copy, and modify this software with or without fee
26 * is hereby granted, provided that this entire notice is included in
27 * all copies of any software which is or includes a copy or
28 * modification of this software.
29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to
32 * all.
33 *
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38 * PURPOSE.
39 */
40
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.45 2017/07/05 03:44:59 ozaki-r Exp $");
43
44 /*
45 * IPsec input processing.
46 */
47
48 #if defined(_KERNEL_OPT)
49 #include "opt_inet.h"
50 #endif
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/malloc.h>
55 #include <sys/mbuf.h>
56 #include <sys/domain.h>
57 #include <sys/protosw.h>
58 #include <sys/socket.h>
59 #include <sys/errno.h>
60 #include <sys/syslog.h>
61
62 #include <net/if.h>
63 #include <net/route.h>
64
65 #include <netinet/in.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
68 #include <netinet/ip_var.h>
69 #include <netinet/in_var.h>
70 #include <netinet/in_proto.h>
71 #include <netinet/udp.h>
72 #include <netinet/tcp.h>
73
74 #include <netinet/ip6.h>
75 #ifdef INET6
76 #include <netinet6/ip6_var.h>
77 #include <netinet6/ip6_private.h>
78 #include <netinet6/scope6_var.h>
79 #endif
80 #include <netinet/in_pcb.h>
81 #ifdef INET6
82 #include <netinet/icmp6.h>
83 #endif
84
85 #include <netipsec/ipsec.h>
86 #include <netipsec/ipsec_private.h>
87 #ifdef INET6
88 #include <netipsec/ipsec6.h>
89 #endif
90 #include <netipsec/ah_var.h>
91 #include <netipsec/esp.h>
92 #include <netipsec/esp_var.h>
93 #include <netipsec/ipcomp_var.h>
94
95 #include <netipsec/key.h>
96 #include <netipsec/keydb.h>
97
98 #include <netipsec/xform.h>
99 #include <netinet6/ip6protosw.h>
100
101 #include <net/net_osdep.h>
102
103 #define IPSEC_ISTAT(p, x, y, z) \
104 do { \
105 switch (p) { \
106 case IPPROTO_ESP: \
107 ESP_STATINC(x); \
108 break; \
109 case IPPROTO_AH: \
110 AH_STATINC(y); \
111 break; \
112 default: \
113 IPCOMP_STATINC(z); \
114 break; \
115 } \
116 } while (/*CONSTCOND*/0)
117
118 /*
119 * fixup TCP/UDP checksum
120 *
121 * XXX: if we have NAT-OA payload from IKE server,
122 * we must do the differential update of checksum.
123 *
124 * XXX: NAT-OAi/NAT-OAr drived from IKE initiator/responder.
125 * how to know the IKE side from kernel?
126 */
127 static struct mbuf *
128 ipsec4_fixup_checksum(struct mbuf *m)
129 {
130 struct ip *ip;
131 struct tcphdr *th;
132 struct udphdr *uh;
133 int poff, off;
134 int plen;
135
136 if (m->m_len < sizeof(*ip))
137 m = m_pullup(m, sizeof(*ip));
138 ip = mtod(m, struct ip *);
139 poff = ip->ip_hl << 2;
140 plen = ntohs(ip->ip_len) - poff;
141
142 switch (ip->ip_p) {
143 case IPPROTO_TCP:
144 IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
145 if (th == NULL)
146 return NULL;
147 off = th->th_off << 2;
148 if (off < sizeof(*th) || off > plen) {
149 m_freem(m);
150 return NULL;
151 }
152 th->th_sum = 0;
153 th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
154 break;
155 case IPPROTO_UDP:
156 IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
157 if (uh == NULL)
158 return NULL;
159 off = sizeof(*uh);
160 if (off > plen) {
161 m_freem(m);
162 return NULL;
163 }
164 uh->uh_sum = 0;
165 uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
166 break;
167 default:
168 /* no checksum */
169 return m;
170 }
171
172 return m;
173 }
174
175 /*
176 * ipsec_common_input gets called when an IPsec-protected packet
177 * is received by IPv4 or IPv6. It's job is to find the right SA
178 # and call the appropriate transform. The transform callback
179 * takes care of further processing (like ingress filtering).
180 */
181 static int
182 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
183 {
184 char buf[IPSEC_ADDRSTRLEN];
185 union sockaddr_union dst_address;
186 struct secasvar *sav;
187 u_int32_t spi;
188 u_int16_t sport;
189 u_int16_t dport;
190 int s, error;
191
192 IPSEC_ISTAT(sproto, ESP_STAT_INPUT, AH_STAT_INPUT,
193 IPCOMP_STAT_INPUT);
194
195 KASSERT(m != NULL);
196
197 if ((sproto == IPPROTO_ESP && !esp_enable) ||
198 (sproto == IPPROTO_AH && !ah_enable) ||
199 (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
200 m_freem(m);
201 IPSEC_ISTAT(sproto, ESP_STAT_PDROPS, AH_STAT_PDROPS,
202 IPCOMP_STAT_PDROPS);
203 return EOPNOTSUPP;
204 }
205
206 if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) {
207 m_freem(m);
208 IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
209 IPCOMP_STAT_HDROPS);
210 IPSECLOG(LOG_DEBUG, "packet too small\n");
211 return EINVAL;
212 }
213
214 /* Retrieve the SPI from the relevant IPsec header */
215 if (sproto == IPPROTO_ESP)
216 m_copydata(m, skip, sizeof(u_int32_t), &spi);
217 else if (sproto == IPPROTO_AH)
218 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), &spi);
219 else if (sproto == IPPROTO_IPCOMP) {
220 u_int16_t cpi;
221 m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), &cpi);
222 spi = ntohl(htons(cpi));
223 } else {
224 panic("ipsec_common_input called with bad protocol number :"
225 "%d\n", sproto);
226 }
227
228
229 /* find the source port for NAT-T */
230 nat_t_ports_get(m, &dport, &sport);
231
232 /*
233 * Find the SA and (indirectly) call the appropriate
234 * kernel crypto routine. The resulting mbuf chain is a valid
235 * IP packet ready to go through input processing.
236 */
237 memset(&dst_address, 0, sizeof (dst_address));
238 dst_address.sa.sa_family = af;
239 switch (af) {
240 #ifdef INET
241 case AF_INET:
242 dst_address.sin.sin_len = sizeof(struct sockaddr_in);
243 m_copydata(m, offsetof(struct ip, ip_dst),
244 sizeof(struct in_addr),
245 &dst_address.sin.sin_addr);
246 break;
247 #endif /* INET */
248 #ifdef INET6
249 case AF_INET6:
250 dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
251 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
252 sizeof(struct in6_addr),
253 &dst_address.sin6.sin6_addr);
254 if (sa6_recoverscope(&dst_address.sin6)) {
255 m_freem(m);
256 return EINVAL;
257 }
258 break;
259 #endif /* INET6 */
260 default:
261 IPSECLOG(LOG_DEBUG, "unsupported protocol family %u\n", af);
262 m_freem(m);
263 IPSEC_ISTAT(sproto, ESP_STAT_NOPF, AH_STAT_NOPF,
264 IPCOMP_STAT_NOPF);
265 return EPFNOSUPPORT;
266 }
267
268 s = splsoftnet();
269
270 /* NB: only pass dst since key_allocsa follows RFC2401 */
271 sav = KEY_ALLOCSA(&dst_address, sproto, spi, sport, dport);
272 if (sav == NULL) {
273 IPSECLOG(LOG_DEBUG,
274 "no key association found for SA %s/%08lx/%u/%u\n",
275 ipsec_address(&dst_address, buf, sizeof(buf)),
276 (u_long) ntohl(spi), sproto, ntohs(dport));
277 IPSEC_ISTAT(sproto, ESP_STAT_NOTDB, AH_STAT_NOTDB,
278 IPCOMP_STAT_NOTDB);
279 splx(s);
280 m_freem(m);
281 return ENOENT;
282 }
283
284 if (sav->tdb_xform == NULL) {
285 IPSECLOG(LOG_DEBUG,
286 "attempted to use uninitialized SA %s/%08lx/%u\n",
287 ipsec_address(&dst_address, buf, sizeof(buf)),
288 (u_long) ntohl(spi), sproto);
289 IPSEC_ISTAT(sproto, ESP_STAT_NOXFORM, AH_STAT_NOXFORM,
290 IPCOMP_STAT_NOXFORM);
291 KEY_FREESAV(&sav);
292 splx(s);
293 m_freem(m);
294 return ENXIO;
295 }
296
297 /*
298 * Call appropriate transform and return -- callback takes care of
299 * everything else.
300 */
301 error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
302 KEY_FREESAV(&sav);
303 splx(s);
304 return error;
305 }
306
307 #ifdef INET
308 /*
309 * Common input handler for IPv4 AH, ESP, and IPCOMP.
310 */
311 void
312 ipsec4_common_input(struct mbuf *m, ...)
313 {
314 va_list ap;
315 int off, nxt;
316
317 va_start(ap, m);
318 off = va_arg(ap, int);
319 nxt = va_arg(ap, int);
320 va_end(ap);
321
322 (void) ipsec_common_input(m, off, offsetof(struct ip, ip_p),
323 AF_INET, nxt);
324 }
325
326 /*
327 * IPsec input callback for INET protocols.
328 * This routine is called as the transform callback.
329 * Takes care of filtering and other sanity checks on
330 * the processed packet.
331 */
332 int
333 ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
334 int skip, int protoff)
335 {
336 int prot, af __diagused, sproto;
337 struct ip *ip;
338 struct tdb_ident *tdbi;
339 struct secasindex *saidx;
340 int error;
341
342 IPSEC_SPLASSERT_SOFTNET("ipsec4_common_input_cb");
343
344 KASSERT(m != NULL);
345 KASSERT(sav != NULL);
346 KASSERT(sav->sah != NULL);
347 saidx = &sav->sah->saidx;
348 af = saidx->dst.sa.sa_family;
349 KASSERTMSG(af == AF_INET, "unexpected af %u", af);
350 sproto = saidx->proto;
351 KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
352 sproto == IPPROTO_IPCOMP,
353 "unexpected security protocol %u", sproto);
354
355 /* Sanity check */
356 if (m == NULL) {
357 IPSECLOG(LOG_DEBUG, "null mbuf");
358 IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
359 IPCOMP_STAT_BADKCR);
360 KEY_FREESAV(&sav);
361 return EINVAL;
362 }
363
364 /* Fix IPv4 header */
365 if (skip != 0) {
366 if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
367 char buf[IPSEC_ADDRSTRLEN];
368 cantpull:
369 IPSECLOG(LOG_DEBUG,
370 "processing failed for SA %s/%08lx\n",
371 ipsec_address(&sav->sah->saidx.dst, buf,
372 sizeof(buf)), (u_long) ntohl(sav->spi));
373 IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
374 IPCOMP_STAT_HDROPS);
375 error = ENOBUFS;
376 goto bad;
377 }
378
379 ip = mtod(m, struct ip *);
380 ip->ip_len = htons(m->m_pkthdr.len);
381 ip->ip_sum = 0;
382 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
383 } else {
384 ip = mtod(m, struct ip *);
385 }
386
387 /*
388 * Update TCP/UDP checksum
389 * XXX: should only do it in NAT-T case
390 * XXX: should do it incrementally, see FreeBSD code.
391 */
392 m = ipsec4_fixup_checksum(m);
393 if (m == NULL)
394 goto cantpull;
395
396 prot = ip->ip_p;
397
398 /* IP-in-IP encapsulation */
399 if (prot == IPPROTO_IPIP) {
400 struct ip ipn;
401
402 /* ipn will now contain the inner IPv4 header */
403 m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), &ipn);
404
405 #ifdef notyet
406 /* XXX PROXY address isn't recorded in SAH */
407 /*
408 * Check that the inner source address is the same as
409 * the proxy address, if available.
410 */
411 if ((saidx->proxy.sa.sa_family == AF_INET &&
412 saidx->proxy.sin.sin_addr.s_addr !=
413 INADDR_ANY &&
414 ipn.ip_src.s_addr !=
415 saidx->proxy.sin.sin_addr.s_addr) ||
416 (saidx->proxy.sa.sa_family != AF_INET &&
417 saidx->proxy.sa.sa_family != 0)) {
418
419 char ipbuf[INET_ADDRSTRLEN];
420 IPSECLOG(LOG_DEBUG,
421 "inner source address %s doesn't correspond to "
422 "expected proxy source %s, SA %s/%08lx\n",
423 IN_PRINT(ipbuf, ipn.ip_src),
424 ipsp_address(saidx->proxy),
425 ipsp_address(saidx->dst),
426 (u_long) ntohl(sav->spi));
427
428 IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
429 AH_STAT_PDROPS,
430 IPCOMP_STAT_PDROPS);
431 error = EACCES;
432 goto bad;
433 }
434 #endif /*XXX*/
435 }
436 #if INET6
437 /* IPv6-in-IP encapsulation. */
438 if (prot == IPPROTO_IPV6) {
439 struct ip6_hdr ip6n;
440
441 /* ip6n will now contain the inner IPv6 header. */
442 m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), &ip6n);
443
444 #ifdef notyet
445 /*
446 * Check that the inner source address is the same as
447 * the proxy address, if available.
448 */
449 if ((saidx->proxy.sa.sa_family == AF_INET6 &&
450 !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
451 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
452 &saidx->proxy.sin6.sin6_addr)) ||
453 (saidx->proxy.sa.sa_family != AF_INET6 &&
454 saidx->proxy.sa.sa_family != 0)) {
455
456 char ip6buf[INET6_ADDRSTRLEN];
457 char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
458 IPSECLOG(LOG_DEBUG,
459 "inner source address %s doesn't correspond to "
460 "expected proxy source %s, SA %s/%08lx\n",
461 ip6_sprintf(ip6buf, &ip6n.ip6_src),
462 ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
463 ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
464 (u_long) ntohl(sav->spi));
465
466 IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
467 AH_STAT_PDROPS,
468 IPCOMP_STAT_PDROPS);
469 error = EACCES;
470 goto bad;
471 }
472 #endif /*XXX*/
473 }
474 #endif /* INET6 */
475
476 /*
477 * Record what we've done to the packet (under what SA it was
478 * processed).
479 */
480 if (sproto != IPPROTO_IPCOMP) {
481 struct m_tag *mtag;
482 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
483 sizeof(struct tdb_ident), M_NOWAIT);
484 if (mtag == NULL) {
485 IPSECLOG(LOG_DEBUG, "failed to get tag\n");
486 IPSEC_ISTAT(sproto, ESP_STAT_HDROPS,
487 AH_STAT_HDROPS, IPCOMP_STAT_HDROPS);
488 error = ENOMEM;
489 goto bad;
490 }
491
492 tdbi = (struct tdb_ident *)(mtag + 1);
493 memcpy(&tdbi->dst, &saidx->dst, saidx->dst.sa.sa_len);
494 tdbi->proto = sproto;
495 tdbi->spi = sav->spi;
496
497 m_tag_prepend(m, mtag);
498 }
499
500 key_sa_recordxfer(sav, m); /* record data transfer */
501
502 if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 &&
503 ipsec4_in_reject(m, NULL)) {
504 error = EINVAL;
505 goto bad;
506 }
507 (*inetsw[ip_protox[prot]].pr_input)(m, skip, prot);
508 return 0;
509 bad:
510 m_freem(m);
511 return error;
512 }
513 #endif /* INET */
514
515 #ifdef INET6
516 /* IPv6 AH wrapper. */
517 int
518 ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
519 {
520 int l = 0;
521 int protoff, nxt;
522 struct ip6_ext ip6e;
523
524 if (*offp < sizeof(struct ip6_hdr)) {
525 IPSECLOG(LOG_DEBUG, "bad offset %u\n", *offp);
526 IPSEC_ISTAT(proto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
527 IPCOMP_STAT_HDROPS);
528 m_freem(*mp);
529 return IPPROTO_DONE;
530 } else if (*offp == sizeof(struct ip6_hdr)) {
531 protoff = offsetof(struct ip6_hdr, ip6_nxt);
532 } else {
533 /* Chase down the header chain... */
534 protoff = sizeof(struct ip6_hdr);
535 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
536
537 do {
538 protoff += l;
539 m_copydata(*mp, protoff, sizeof(ip6e), &ip6e);
540
541 if (nxt == IPPROTO_AH)
542 l = (ip6e.ip6e_len + 2) << 2;
543 else
544 l = (ip6e.ip6e_len + 1) << 3;
545 KASSERT(l > 0);
546
547 nxt = ip6e.ip6e_nxt;
548 } while (protoff + l < *offp);
549
550 /* Malformed packet check */
551 if (protoff + l != *offp) {
552 IPSECLOG(LOG_DEBUG, "bad packet header chain, "
553 "protoff %u, l %u, off %u\n", protoff, l, *offp);
554 IPSEC_ISTAT(proto, ESP_STAT_HDROPS,
555 AH_STAT_HDROPS,
556 IPCOMP_STAT_HDROPS);
557 m_freem(*mp);
558 *mp = NULL;
559 return IPPROTO_DONE;
560 }
561 protoff += offsetof(struct ip6_ext, ip6e_nxt);
562 }
563 (void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
564 return IPPROTO_DONE;
565 }
566
567 extern const struct ip6protosw inet6sw[];
568 extern u_char ip6_protox[];
569
570 /*
571 * IPsec input callback, called by the transform callback. Takes care of
572 * filtering and other sanity checks on the processed packet.
573 */
574 int
575 ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
576 int protoff)
577 {
578 int af __diagused, sproto;
579 struct ip6_hdr *ip6;
580 struct tdb_ident *tdbi;
581 struct secasindex *saidx;
582 int nxt;
583 u_int8_t prot, nxt8;
584 int error, nest;
585
586 KASSERT(m != NULL);
587 KASSERT(sav != NULL);
588 KASSERT(sav->sah != NULL);
589 saidx = &sav->sah->saidx;
590 af = saidx->dst.sa.sa_family;
591 KASSERTMSG(af == AF_INET6, "unexpected af %u", af);
592 sproto = saidx->proto;
593 KASSERTMSG(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
594 sproto == IPPROTO_IPCOMP,
595 "unexpected security protocol %u", sproto);
596
597 /* Sanity check */
598 if (m == NULL) {
599 IPSECLOG(LOG_DEBUG, "null mbuf");
600 IPSEC_ISTAT(sproto, ESP_STAT_BADKCR, AH_STAT_BADKCR,
601 IPCOMP_STAT_BADKCR);
602 error = EINVAL;
603 goto bad;
604 }
605
606 /* Fix IPv6 header */
607 if (m->m_len < sizeof(struct ip6_hdr) &&
608 (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
609
610 char buf[IPSEC_ADDRSTRLEN];
611 IPSECLOG(LOG_DEBUG, "processing failed for SA %s/%08lx\n",
612 ipsec_address(&sav->sah->saidx.dst,
613 buf, sizeof(buf)), (u_long) ntohl(sav->spi));
614
615 IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS,
616 IPCOMP_STAT_HDROPS);
617 error = EACCES;
618 goto bad;
619 }
620
621 ip6 = mtod(m, struct ip6_hdr *);
622 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
623
624 /* Save protocol */
625 m_copydata(m, protoff, 1, &prot);
626
627 #ifdef INET
628 /* IP-in-IP encapsulation */
629 if (prot == IPPROTO_IPIP) {
630 struct ip ipn;
631
632 /* ipn will now contain the inner IPv4 header */
633 m_copydata(m, skip, sizeof(struct ip), &ipn);
634
635 #ifdef notyet
636 /*
637 * Check that the inner source address is the same as
638 * the proxy address, if available.
639 */
640 if ((saidx->proxy.sa.sa_family == AF_INET &&
641 saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
642 ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
643 (saidx->proxy.sa.sa_family != AF_INET &&
644 saidx->proxy.sa.sa_family != 0)) {
645
646 char ipbuf[INET_ADDRSTRLEN];
647 char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
648 IPSECLOG(LOG_DEBUG,
649 "inner source address %s doesn't correspond to "
650 "expected proxy source %s, SA %s/%08lx\n",
651 IN_PRINT(ipbuf, ipn.ip_src),
652 ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
653 ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
654 (u_long) ntohl(sav->spi));
655
656 IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
657 AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
658 error = EACCES;
659 goto bad;
660 }
661 #endif /*XXX*/
662 }
663 #endif /* INET */
664
665 /* IPv6-in-IP encapsulation */
666 if (prot == IPPROTO_IPV6) {
667 struct ip6_hdr ip6n;
668
669 /* ip6n will now contain the inner IPv6 header. */
670 m_copydata(m, skip, sizeof(struct ip6_hdr), &ip6n);
671
672 #ifdef notyet
673 /*
674 * Check that the inner source address is the same as
675 * the proxy address, if available.
676 */
677 if ((saidx->proxy.sa.sa_family == AF_INET6 &&
678 !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
679 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
680 &saidx->proxy.sin6.sin6_addr)) ||
681 (saidx->proxy.sa.sa_family != AF_INET6 &&
682 saidx->proxy.sa.sa_family != 0)) {
683
684 char ip6buf[INET6_ADDRSTRLEN];
685 char pbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
686 IPSECLOG(LOG_DEBUG,
687 "inner source address %s doesn't correspond to "
688 "expected proxy source %s, SA %s/%08lx\n",
689 ip6_sprintf(ip6buf, &ip6n.ip6_src),
690 ipsec_address(&saidx->proxy, pbuf, sizeof(pbuf)),
691 ipsec_address(&saidx->dst, dbuf, sizeof(dbuf)),
692 (u_long) ntohl(sav->spi));
693
694 IPSEC_ISTAT(sproto, ESP_STAT_PDROPS,
695 AH_STAT_PDROPS, IPCOMP_STAT_PDROPS);
696 error = EACCES;
697 goto bad;
698 }
699 #endif /*XXX*/
700 }
701
702 /*
703 * Record what we've done to the packet (under what SA it was
704 * processed).
705 */
706 if (sproto != IPPROTO_IPCOMP) {
707 struct m_tag *mtag;
708 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
709 sizeof(struct tdb_ident), M_NOWAIT);
710 if (mtag == NULL) {
711 IPSECLOG(LOG_DEBUG, "failed to get tag\n");
712 IPSEC_ISTAT(sproto, ESP_STAT_HDROPS,
713 AH_STAT_HDROPS, IPCOMP_STAT_HDROPS);
714 error = ENOMEM;
715 goto bad;
716 }
717
718 tdbi = (struct tdb_ident *)(mtag + 1);
719 memcpy(&tdbi->dst, &saidx->dst, sizeof(union sockaddr_union));
720 tdbi->proto = sproto;
721 tdbi->spi = sav->spi;
722
723 m_tag_prepend(m, mtag);
724 }
725
726 key_sa_recordxfer(sav, m);
727
728 /* Retrieve new protocol */
729 m_copydata(m, protoff, sizeof(u_int8_t), &nxt8);
730
731 /*
732 * See the end of ip6_input for this logic.
733 * IPPROTO_IPV[46] case will be processed just like other ones
734 */
735 nest = 0;
736 nxt = nxt8;
737 while (nxt != IPPROTO_DONE) {
738 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
739 IP6_STATINC(IP6_STAT_TOOMANYHDR);
740 error = EINVAL;
741 goto bad;
742 }
743
744 /*
745 * Protection against faulty packet - there should be
746 * more sanity checks in header chain processing.
747 */
748 if (m->m_pkthdr.len < skip) {
749 IP6_STATINC(IP6_STAT_TOOSHORT);
750 in6_ifstat_inc(m_get_rcvif_NOMPSAFE(m),
751 ifs6_in_truncated);
752 error = EINVAL;
753 goto bad;
754 }
755 /*
756 * Enforce IPsec policy checking if we are seeing last header.
757 * note that we do not visit this with protocols with pcb layer
758 * code - like udp/tcp/raw ip.
759 */
760 if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
761 ipsec6_in_reject(m, NULL)) {
762 error = EINVAL;
763 goto bad;
764 }
765 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
766 }
767 return 0;
768 bad:
769 if (m)
770 m_freem(m);
771 return error;
772 }
773 #endif /* INET6 */
774