xref: /openbsd-src/sys/netinet/ip_ipip.c (revision 850e275390052b330d93020bf619a739a3c277ac)
1 /*	$OpenBSD: ip_ipip.c,v 1.41 2008/06/10 09:57:51 todd 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  * The original version of this code was written by John Ioannidis
8  * for BSD/OS in Athens, Greece, 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 /*
39  * IP-inside-IP processing
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/mbuf.h>
45 #include <sys/socket.h>
46 #include <sys/sysctl.h>
47 
48 #include <net/if.h>
49 #include <net/route.h>
50 #include <net/netisr.h>
51 #include <net/bpf.h>
52 
53 #include <netinet/in.h>
54 #include <netinet/in_systm.h>
55 #include <netinet/ip.h>
56 #include <netinet/in_pcb.h>
57 #include <netinet/in_var.h>
58 #include <netinet/ip_var.h>
59 #include <netinet/ip_ecn.h>
60 
61 #ifdef MROUTING
62 #include <netinet/ip_mroute.h>
63 #endif
64 
65 #include <netinet/ip_ipsp.h>
66 #include <netinet/ip_ipip.h>
67 
68 #include "bpfilter.h"
69 
70 #ifdef ENCDEBUG
71 #define DPRINTF(x)	if (encdebug) printf x
72 #else
73 #define DPRINTF(x)
74 #endif
75 
76 /*
77  * We can control the acceptance of IP4 packets by altering the sysctl
78  * net.inet.ipip.allow value.  Zero means drop them, all else is acceptance.
79  */
80 int ipip_allow = 0;
81 
82 struct ipipstat ipipstat;
83 
84 #ifdef INET6
85 /*
86  * Really only a wrapper for ipip_input(), for use with IPv6.
87  */
88 int
89 ip4_input6(struct mbuf **m, int *offp, int proto)
90 {
91 	/* If we do not accept IP-in-IP explicitly, drop.  */
92 	if (!ipip_allow && ((*m)->m_flags & (M_AUTH|M_CONF)) == 0) {
93 		DPRINTF(("ip4_input6(): dropped due to policy\n"));
94 		ipipstat.ipips_pdrops++;
95 		m_freem(*m);
96 		return IPPROTO_DONE;
97 	}
98 
99 	ipip_input(*m, *offp, NULL);
100 	return IPPROTO_DONE;
101 }
102 #endif /* INET6 */
103 
104 #ifdef INET
105 /*
106  * Really only a wrapper for ipip_input(), for use with IPv4.
107  */
108 void
109 ip4_input(struct mbuf *m, ...)
110 {
111 	va_list ap;
112 	int iphlen;
113 
114 	/* If we do not accept IP-in-IP explicitly, drop.  */
115 	if (!ipip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) {
116 		DPRINTF(("ip4_input(): dropped due to policy\n"));
117 		ipipstat.ipips_pdrops++;
118 		m_freem(m);
119 		return;
120 	}
121 
122 	va_start(ap, m);
123 	iphlen = va_arg(ap, int);
124 	va_end(ap);
125 
126 	ipip_input(m, iphlen, NULL);
127 }
128 #endif /* INET */
129 
130 /*
131  * ipip_input gets called when we receive an IP{46} encapsulated packet,
132  * either because we got it at a real interface, or because AH or ESP
133  * were being used in tunnel mode (in which case the rcvif element will
134  * contain the address of the encX interface associated with the tunnel.
135  */
136 
137 void
138 ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
139 {
140 	struct sockaddr_in *sin;
141 	struct ifnet *ifp;
142 	struct ifaddr *ifa;
143 	struct ifqueue *ifq = NULL;
144 	struct ip *ipo;
145 #ifdef INET6
146 	struct sockaddr_in6 *sin6;
147 	struct ip6_hdr *ip6 = NULL;
148 	u_int8_t itos;
149 #endif
150 	u_int8_t nxt;
151 	int isr;
152 	u_int8_t otos;
153 	u_int8_t v;
154 	int hlen, s;
155 
156 	ipipstat.ipips_ipackets++;
157 
158 	m_copydata(m, 0, 1, &v);
159 
160 	switch (v >> 4) {
161 #ifdef INET
162         case 4:
163 		hlen = sizeof(struct ip);
164 		break;
165 #endif /* INET */
166 #ifdef INET6
167         case 6:
168 		hlen = sizeof(struct ip6_hdr);
169 		break;
170 #endif
171         default:
172 		ipipstat.ipips_family++;
173 		m_freem(m);
174 		return /* EAFNOSUPPORT */;
175 	}
176 
177 	/* Bring the IP header in the first mbuf, if not there already */
178 	if (m->m_len < hlen) {
179 		if ((m = m_pullup(m, hlen)) == NULL) {
180 			DPRINTF(("ipip_input(): m_pullup() failed\n"));
181 			ipipstat.ipips_hdrops++;
182 			return;
183 		}
184 	}
185 
186 	ipo = mtod(m, struct ip *);
187 
188 	/* Keep outer ecn field. */
189 	switch (v >> 4) {
190 #ifdef INET
191 	case 4:
192 		otos = ipo->ip_tos;
193 		break;
194 #endif /* INET */
195 #ifdef INET6
196 	case 6:
197 		otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff;
198 		break;
199 #endif
200 	default:
201 		panic("ipip_input: should never reach here");
202 	}
203 
204 	/* Remove outer IP header */
205 	m_adj(m, iphlen);
206 
207 	/* Sanity check */
208 	if (m->m_pkthdr.len < sizeof(struct ip)) {
209 		ipipstat.ipips_hdrops++;
210 		m_freem(m);
211 		return;
212 	}
213 
214 	m_copydata(m, 0, 1, &v);
215 
216 	switch (v >> 4) {
217 #ifdef INET
218         case 4:
219 		hlen = sizeof(struct ip);
220 		break;
221 #endif /* INET */
222 
223 #ifdef INET6
224         case 6:
225 		hlen = sizeof(struct ip6_hdr);
226 		break;
227 #endif
228 	default:
229 		ipipstat.ipips_family++;
230 		m_freem(m);
231 		return; /* EAFNOSUPPORT */
232 	}
233 
234 	/*
235 	 * Bring the inner IP header in the first mbuf, if not there already.
236 	 */
237 	if (m->m_len < hlen) {
238 		if ((m = m_pullup(m, hlen)) == NULL) {
239 			DPRINTF(("ipip_input(): m_pullup() failed\n"));
240 			ipipstat.ipips_hdrops++;
241 			return;
242 		}
243 	}
244 
245 	/*
246 	 * RFC 1853 specifies that the inner TTL should not be touched on
247 	 * decapsulation. There's no reason this comment should be here, but
248 	 * this is as good as any a position.
249 	 */
250 
251 	/* Some sanity checks in the inner IP header */
252 	switch (v >> 4) {
253 #ifdef INET
254     	case 4:
255                 ipo = mtod(m, struct ip *);
256                 nxt = ipo->ip_p;
257 		if (!ip_ecn_egress(ECN_ALLOWED, &otos, &ipo->ip_tos)) {
258 			m_freem(m);
259 			return;
260 		}
261                 break;
262 #endif /* INET */
263 #ifdef INET6
264     	case 6:
265                 ip6 = (struct ip6_hdr *) ipo;
266                 nxt = ip6->ip6_nxt;
267 		itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
268 		if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) {
269 			m_freem(m);
270 			return;
271 		}
272 		ip6->ip6_flow &= ~htonl(0xff << 20);
273 		ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
274                 break;
275 #endif
276 	default:
277 		panic("ipip_input: should never reach here");
278 	}
279 
280 	/* Check for local address spoofing. */
281 	if ((m->m_pkthdr.rcvif == NULL ||
282 	    !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
283 	    ipip_allow != 2) {
284 		TAILQ_FOREACH(ifp, &ifnet, if_list) {
285 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
286 #ifdef INET
287 				if (ipo) {
288 					if (ifa->ifa_addr->sa_family !=
289 					    AF_INET)
290 						continue;
291 
292 					sin = (struct sockaddr_in *) ifa->ifa_addr;
293 
294 					if (sin->sin_addr.s_addr ==
295 					    ipo->ip_src.s_addr)	{
296 						ipipstat.ipips_spoof++;
297 						m_freem(m);
298 						return;
299 					}
300 				}
301 #endif /* INET */
302 
303 #ifdef INET6
304 				if (ip6) {
305 					if (ifa->ifa_addr->sa_family !=
306 					    AF_INET6)
307 						continue;
308 
309 					sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
310 
311 					if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) {
312 						ipipstat.ipips_spoof++;
313 						m_freem(m);
314 						return;
315 					}
316 
317 				}
318 #endif /* INET6 */
319 			}
320 		}
321 	}
322 
323 	/* Statistics */
324 	ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen;
325 
326 	/*
327 	 * Interface pointer stays the same; if no IPsec processing has
328 	 * been done (or will be done), this will point to a normal
329 	 * interface. Otherwise, it'll point to an enc interface, which
330 	 * will allow a packet filter to distinguish between secure and
331 	 * untrusted packets.
332 	 */
333 
334 	switch (v >> 4) {
335 #ifdef INET
336 	case 4:
337 		ifq = &ipintrq;
338 		isr = NETISR_IP;
339 		break;
340 #endif
341 #ifdef INET6
342 	case 6:
343 		ifq = &ip6intrq;
344 		isr = NETISR_IPV6;
345 		break;
346 #endif
347 	default:
348 		panic("ipip_input: should never reach here");
349 	}
350 
351 #if NBPFILTER > 0
352 	if (gifp && gifp->if_bpf)
353 		bpf_mtap_af(gifp->if_bpf, ifq == &ipintrq ? AF_INET : AF_INET6,
354 		    m, BPF_DIRECTION_IN);
355 #endif
356 
357 	s = splnet();			/* isn't it already? */
358 	if (IF_QFULL(ifq)) {
359 		IF_DROP(ifq);
360 		m_freem(m);
361 		ipipstat.ipips_qfull++;
362 
363 		splx(s);
364 
365 		DPRINTF(("ipip_input(): packet dropped because of full "
366 		    "queue\n"));
367 		return;
368 	}
369 
370 	IF_ENQUEUE(ifq, m);
371 	schednetisr(isr);
372 	splx(s);
373 	return;
374 }
375 
376 int
377 ipip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int dummy,
378     int dummy2)
379 {
380 	u_int8_t tp, otos;
381 
382 #ifdef INET
383 	u_int8_t itos;
384 	struct ip *ipo;
385 #endif /* INET */
386 
387 #ifdef INET6
388 	struct ip6_hdr *ip6, *ip6o;
389 #endif /* INET6 */
390 
391 	/* XXX Deal with empty TDB source/destination addresses. */
392 
393 	m_copydata(m, 0, 1, &tp);
394 	tp = (tp >> 4) & 0xff;  /* Get the IP version number. */
395 
396 	switch (tdb->tdb_dst.sa.sa_family) {
397 #ifdef INET
398 	case AF_INET:
399 		if (tdb->tdb_src.sa.sa_family != AF_INET ||
400 		    tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY ||
401 		    tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY) {
402 
403 			DPRINTF(("ipip_output(): unspecified tunnel endpoind "
404 			    "address in SA %s/%08x\n",
405 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
406 
407 			ipipstat.ipips_unspec++;
408 			m_freem(m);
409 			*mp = NULL;
410 			return EINVAL;
411 		}
412 
413 		M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
414 		if (m == 0) {
415 			DPRINTF(("ipip_output(): M_PREPEND failed\n"));
416 			ipipstat.ipips_hdrops++;
417 			*mp = NULL;
418 			return ENOBUFS;
419 		}
420 
421 		ipo = mtod(m, struct ip *);
422 
423 		ipo->ip_v = IPVERSION;
424 		ipo->ip_hl = 5;
425 		ipo->ip_len = htons(m->m_pkthdr.len);
426 		ipo->ip_ttl = ip_defttl;
427 		ipo->ip_sum = 0;
428 		ipo->ip_src = tdb->tdb_src.sin.sin_addr;
429 		ipo->ip_dst = tdb->tdb_dst.sin.sin_addr;
430 
431 		/*
432 		 * We do the htons() to prevent snoopers from determining our
433 		 * endianness.
434 		 */
435 		ipo->ip_id = htons(ip_randomid());
436 
437 		/* If the inner protocol is IP... */
438 		if (tp == IPVERSION) {
439 			/* Save ECN notification */
440 			m_copydata(m, sizeof(struct ip) +
441 			    offsetof(struct ip, ip_tos),
442 			    sizeof(u_int8_t), (caddr_t) &itos);
443 
444 			ipo->ip_p = IPPROTO_IPIP;
445 
446 			/*
447 			 * We should be keeping tunnel soft-state and
448 			 * send back ICMPs if needed.
449 			 */
450 			m_copydata(m, sizeof(struct ip) +
451 			    offsetof(struct ip, ip_off),
452 			    sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
453 			NTOHS(ipo->ip_off);
454 			ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
455 			HTONS(ipo->ip_off);
456 		}
457 #ifdef INET6
458 		else if (tp == (IPV6_VERSION >> 4)) {
459 			u_int32_t itos32;
460 
461 			/* Save ECN notification. */
462 			m_copydata(m, sizeof(struct ip) +
463 			    offsetof(struct ip6_hdr, ip6_flow),
464 			    sizeof(u_int32_t), (caddr_t) &itos32);
465 			itos = ntohl(itos32) >> 20;
466 			ipo->ip_p = IPPROTO_IPV6;
467 			ipo->ip_off = 0;
468 		}
469 #endif /* INET6 */
470 		else {
471 			m_freem(m);
472 			*mp = NULL;
473 			ipipstat.ipips_family++;
474 			return EAFNOSUPPORT;
475 		}
476 
477 		otos = 0;
478 		ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
479 		ipo->ip_tos = otos;
480 		break;
481 #endif /* INET */
482 
483 #ifdef INET6
484 	case AF_INET6:
485 		if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) ||
486 		    tdb->tdb_src.sa.sa_family != AF_INET6 ||
487 		    IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) {
488 
489 			DPRINTF(("ipip_output(): unspecified tunnel endpoind "
490 			    "address in SA %s/%08x\n",
491 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
492 
493 			ipipstat.ipips_unspec++;
494 			m_freem(m);
495 			*mp = NULL;
496 			return ENOBUFS;
497 		}
498 
499 		/* If the inner protocol is IPv6, clear link local scope */
500 		if (tp == (IPV6_VERSION >> 4)) {
501 			/* scoped address handling */
502 			ip6 = mtod(m, struct ip6_hdr *);
503 			if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
504 				ip6->ip6_src.s6_addr16[1] = 0;
505 			if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
506 				ip6->ip6_dst.s6_addr16[1] = 0;
507 		}
508 
509 		M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
510 		if (m == 0) {
511 			DPRINTF(("ipip_output(): M_PREPEND failed\n"));
512 			ipipstat.ipips_hdrops++;
513 			*mp = NULL;
514 			return ENOBUFS;
515 		}
516 
517 		/* Initialize IPv6 header */
518 		ip6o = mtod(m, struct ip6_hdr *);
519 		ip6o->ip6_flow = 0;
520 		ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
521 		ip6o->ip6_vfc |= IPV6_VERSION;
522 		ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o));
523 		ip6o->ip6_hlim = ip_defttl;
524 		in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL, NULL);
525 		in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL, NULL);
526 
527 #ifdef INET
528 		if (tp == IPVERSION) {
529 			/* Save ECN notification */
530 			m_copydata(m, sizeof(struct ip6_hdr) +
531 			    offsetof(struct ip, ip_tos), sizeof(u_int8_t),
532 			    (caddr_t) &itos);
533 
534 			/* This is really IPVERSION. */
535 			ip6o->ip6_nxt = IPPROTO_IPIP;
536 		}
537 		else
538 #endif /* INET */
539 			if (tp == (IPV6_VERSION >> 4)) {
540 				u_int32_t itos32;
541 
542 				/* Save ECN notification. */
543 				m_copydata(m, sizeof(struct ip6_hdr) +
544 				    offsetof(struct ip6_hdr, ip6_flow),
545 				    sizeof(u_int32_t), (caddr_t) &itos32);
546 				itos = ntohl(itos32) >> 20;
547 
548 				ip6o->ip6_nxt = IPPROTO_IPV6;
549 			} else {
550 				m_freem(m);
551 				*mp = NULL;
552 				ipipstat.ipips_family++;
553 				return EAFNOSUPPORT;
554 			}
555 
556 		otos = 0;
557 		ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
558 		ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
559 		break;
560 #endif /* INET6 */
561 
562 	default:
563 		DPRINTF(("ipip_output(): unsupported protocol family %d\n",
564 		    tdb->tdb_dst.sa.sa_family));
565 		m_freem(m);
566 		*mp = NULL;
567 		ipipstat.ipips_family++;
568 		return EAFNOSUPPORT;
569 	}
570 
571 	ipipstat.ipips_opackets++;
572 	*mp = m;
573 
574 #ifdef INET
575 	if (tdb->tdb_dst.sa.sa_family == AF_INET) {
576 		if (tdb->tdb_xform->xf_type == XF_IP4)
577 			tdb->tdb_cur_bytes +=
578 			    m->m_pkthdr.len - sizeof(struct ip);
579 
580 		ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip);
581 	}
582 #endif /* INET */
583 
584 #ifdef INET6
585 	if (tdb->tdb_dst.sa.sa_family == AF_INET6) {
586 		if (tdb->tdb_xform->xf_type == XF_IP4)
587 			tdb->tdb_cur_bytes +=
588 			    m->m_pkthdr.len - sizeof(struct ip6_hdr);
589 
590 		ipipstat.ipips_obytes +=
591 		    m->m_pkthdr.len - sizeof(struct ip6_hdr);
592 	}
593 #endif /* INET6 */
594 
595 	return 0;
596 }
597 
598 #ifdef IPSEC
599 int
600 ipe4_attach()
601 {
602 	return 0;
603 }
604 
605 int
606 ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
607 {
608 	tdbp->tdb_xform = xsp;
609 	return 0;
610 }
611 
612 int
613 ipe4_zeroize(struct tdb *tdbp)
614 {
615 	return 0;
616 }
617 
618 void
619 ipe4_input(struct mbuf *m, ...)
620 {
621 	/* This is a rather serious mistake, so no conditional printing. */
622 	printf("ipe4_input(): should never be called\n");
623 	if (m)
624 		m_freem(m);
625 }
626 #endif	/* IPSEC */
627 
628 int
629 ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
630     size_t newlen)
631 {
632 	/* All sysctl names at this level are terminal. */
633 	if (namelen != 1)
634 		return (ENOTDIR);
635 
636 	switch (name[0]) {
637 	case IPIPCTL_ALLOW:
638 		return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow));
639 	case IPIPCTL_STATS:
640 		if (newp != NULL)
641 			return (EPERM);
642 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
643 		    &ipipstat, sizeof(ipipstat)));
644 	default:
645 		return (ENOPROTOOPT);
646 	}
647 	/* NOTREACHED */
648 }
649