diff options
-rw-r--r-- | sys/conf/files | 4 | ||||
-rw-r--r-- | sys/netinet/in.h | 4 | ||||
-rw-r--r-- | sys/netinet/in_gif.c | 13 | ||||
-rw-r--r-- | sys/netinet/in_proto.c | 8 | ||||
-rw-r--r-- | sys/netinet/ip_ipip.c | 655 | ||||
-rw-r--r-- | sys/netinet/ip_ipip.h (renamed from sys/netinet/ip_ip4.h) | 44 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 8 | ||||
-rw-r--r-- | sys/netinet/ip_mroute.c | 13 | ||||
-rw-r--r-- | sys/netinet/ip_mroute.h | 4 | ||||
-rw-r--r-- | sys/netinet6/in6_gif.c | 14 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 22 |
12 files changed, 732 insertions, 63 deletions
diff --git a/sys/conf/files b/sys/conf/files index ae1fc01194a..b3d6294c202 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.148 2000/01/11 17:58:50 peter Exp $ +# $OpenBSD: files,v 1.149 2000/01/21 03:15:06 angelos Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -496,7 +496,7 @@ file netinet/ip_proxy.c ipfilter file netinet/ip_auth.c ipfilter file netinet/ip_log.c ipfilter file netinet/ip_ipsp.c (inet | inet6) & (ipsec | tcp_signature) -file netinet/ip_ip4.c inet | inet6 +file netinet/ip_ipip.c inet | inet6 file netinet/ip_ether.c inet & ipsec file netinet/ipsec_input.c (inet | inet6) & ipsec file netinet/ip_xform.c inet & ipsec diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 1ea1358fc51..d5562203bed 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in.h,v 1.35 2000/01/18 19:06:07 angelos Exp $ */ +/* $OpenBSD: in.h,v 1.36 2000/01/21 03:15:04 angelos Exp $ */ /* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */ /* @@ -318,7 +318,7 @@ struct ip_mreq { { "icmp", CTLTYPE_NODE }, \ { "igmp", CTLTYPE_NODE }, \ { "ggp", CTLTYPE_NODE }, \ - { "ip4", CTLTYPE_NODE }, \ + { "ipip", CTLTYPE_NODE }, \ { 0, 0 }, \ { "tcp", CTLTYPE_NODE }, \ { 0, 0 }, \ diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index 52b50cc4a5a..fb29419712d 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_gif.c,v 1.6 2000/01/11 07:47:09 angelos Exp $ */ +/* $OpenBSD: in_gif.c,v 1.7 2000/01/21 03:15:04 angelos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -110,7 +110,7 @@ in_gif_output(ifp, family, m, rt) return ENETUNREACH; } - /* setup dummy tdb. it highly depends on ipe4_output() code. */ + /* setup dummy tdb. it highly depends on ipipoutput() code. */ bzero(&tdb, sizeof(tdb)); bzero(&xfs, sizeof(xfs)); tdb.tdb_src.sin.sin_family = AF_INET; @@ -149,7 +149,7 @@ in_gif_output(ifp, family, m, rt) /* encapsulate into IPv4 packet */ mp = NULL; - error = ipe4_output(m, &tdb, &mp, hlen, poff); + error = ipip_output(m, &tdb, &mp, hlen, poff); if (error) return error; else if (mp == NULL) @@ -223,10 +223,13 @@ in_gif_input(m, va_alist) } } - if (gifp && (m->m_flags & (M_AUTH | M_CONF)) == 0) + if (gifp) { m->m_pkthdr.rcvif = gifp; + ipip_input(m, off); /* We have a configured GIF */ + return; + } inject: - ip4_input(m, off); + ip4_input(m, off); /* No GIF interface was configured */ return; } diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 00b91a4facc..da7125e73fa 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_proto.c,v 1.23 2000/01/17 05:17:24 itojun Exp $ */ +/* $OpenBSD: in_proto.c,v 1.24 2000/01/21 03:15:05 angelos Exp $ */ /* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */ /* @@ -159,7 +159,7 @@ void iplinit __P((void)); #include <netinet/ip_ether.h> #endif -#include <netinet/ip_ip4.h> +#include <netinet/ip_ipip.h> #include "gre.h" #if NGRE > 0 @@ -199,7 +199,7 @@ struct protosw inetsw[] = { { SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR, in_gif_input, rip_output, 0, rip_ctloutput, rip_usrreq, - 0, 0, 0, 0, ip4_sysctl + 0, 0, 0, 0, ipip_sysctl }, #ifdef INET6 { SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, @@ -212,7 +212,7 @@ struct protosw inetsw[] = { { SOCK_RAW, &inetdomain, IPPROTO_IPIP, PR_ATOMIC|PR_ADDR, ip4_input, rip_output, 0, rip_ctloutput, rip_usrreq, - 0, 0, 0, 0, ip4_sysctl + 0, 0, 0, 0, ipip_sysctl }, #ifdef INET6 { SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c new file mode 100644 index 00000000000..383b6133977 --- /dev/null +++ b/sys/netinet/ip_ipip.c @@ -0,0 +1,655 @@ +/* $OpenBSD: ip_ipip.c,v 1.1 2000/01/21 03:15:05 angelos Exp $ */ + +/* + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). + * + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. + * + * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, + * by Angelos D. Keromytis. + * + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. + * + * Additional features in 1999 by Angelos D. Keromytis. + * + * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, + * Angelos D. Keromytis and Niels Provos. + * + * Permission to use, copy, and modify this software without fee + * is hereby granted, provided that this entire notice is included in + * all copies of any software which is or includes a copy or + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR + * PURPOSE. + */ + +/* + * IP-inside-IP processing + */ + + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/domain.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/errno.h> +#include <sys/time.h> +#include <sys/kernel.h> +#include <sys/sysctl.h> +#include <machine/cpu.h> + +#include <net/if.h> +#include <net/route.h> +#include <net/netisr.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/in_pcb.h> +#include <netinet/in_var.h> +#include <netinet/ip_var.h> +#include <netinet/ip_icmp.h> +#include <netinet/ip_ecn.h> + +#ifdef MROUTING +#include <netinet/ip_mroute.h> +#endif + +#include <sys/socketvar.h> +#include <net/raw_cb.h> + +#include <netinet/ip_ipsp.h> +#include <netinet/ip_ipip.h> +#include <dev/rndvar.h> + +#ifdef ENCDEBUG +#define DPRINTF(x) if (encdebug) printf x +#else +#define DPRINTF(x) +#endif + +#ifndef offsetof +#define offsetof(s, e) ((int)&((s *)0)->e) +#endif + +/* + * We can control the acceptance of IP4 packets by altering the sysctl + * net.inet.ipip.allow value. Zero means drop them, all else is acceptance. + */ +int ipip_allow = 0; + +struct ipipstat ipipstat; + +#ifdef INET6 +/* + * Really only a wrapper for ipip_input(), for use with IPv6. + */ +int +ip4_input6(struct mbuf **m, int *offp, int proto) +{ + /* If we do not accept IPv4 explicitly, drop. */ + if (!ipip_allow && ((*m)->m_flags & (M_AUTH|M_CONF)) == 0) + { + DPRINTF(("ip4_input6(): dropped due to policy\n")); + ipipstat.ipips_pdrops++; + m_freem(*m); + return IPPROTO_DONE; + } + + ipip_input(*m, *offp); + return IPPROTO_DONE; +} +#endif /* INET6 */ + +#ifdef INET +/* + * Really only a wrapper for ipip_input(), for use with IPv4. + */ +void +ip4_input(struct mbuf *m, ...) +{ + va_list ap; + int iphlen; + + /* If we do not accept IPv4 explicitly, drop. */ + if (!ipip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) + { + DPRINTF(("ip4_input(): dropped due to policy\n")); + ipipstat.ipips_pdrops++; + m_freem(m); + return; + } + + va_start(ap, m); + iphlen = va_arg(ap, int); + va_end(ap); + + ipip_input(m, iphlen); +} +#endif /* INET */ + +/* + * ipip_input gets called when we receive an IP{46} encapsulated packet, + * either because we got it at a real interface, or because AH or ESP + * were being used in tunnel mode (in which case the rcvif element will + * contain the address of the encX interface associated with the tunnel. + */ + +void +ipip_input(struct mbuf *m, int iphlen) +{ + register struct sockaddr_in *sin; + register struct ifnet *ifp; + register struct ifaddr *ifa; + struct ifqueue *ifq = NULL; + struct ip *ipo; +#ifdef INET6 + register struct sockaddr_in6 *sin6; + struct ip6_hdr *ip6 = NULL; + u_int8_t itos; +#endif + u_int8_t nxt; + int isr; + u_int8_t otos; + u_int8_t v; + int hlen, s; + + ipipstat.ipips_ipackets++; + + m_copydata(m, 0, 1, &v); + + switch (v >> 4) + { +#ifdef INET + case 4: + hlen = sizeof(struct ip); + break; +#endif /* INET */ + +#ifdef INET6 + case 6: + hlen = sizeof(struct ip6_hdr); + break; +#endif + default + m_freem(m); + return /* EAFNOSUPPORT */; + } + + /* Bring the IP header in the first mbuf, if not there already */ + if (m->m_len < hlen) + { + if ((m = m_pullup(m, hlen)) == 0) + { + DPRINTF(("ipip_input(): m_pullup() failed\n")); + ipipstat.ipips_hdrops++; + m_freem(m); + return; + } + } + + ipo = mtod(m, struct ip *); + +#ifdef MROUTING + if (ipo->ip_v == IPVERSION && ipo->ip_p == IPPROTO_IPV4) + { + if (IN_MULTICAST(((struct ip *)((char *) ipo + iphlen))->ip_dst.s_addr)) + { + ipip_mroute_input (m, iphlen); + return; + } + } +#endif MROUTING + + /* keep outer ecn field */ + +#ifdef INET + if ((v >> 4) == 4) + otos = ipo->ip_tos; +#endif /* INET */ + +#ifdef INET6 + if ((v >> 4) == 6) + otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff; +#endif + + /* Remove outter IP header */ + m_adj(m, iphlen); + + m_copydata(m, 0, 1, &v); + + switch (v >> 4) + { +#ifdef INET + case 4: + hlen = sizeof(struct ip); + break; +#endif /* INET */ + +#ifdef INET6 + case 6: + hlen = sizeof(struct ip6_hdr); + break; +#endif + + default: + m_freem(m); + return /* EAFNOSUPPORT */; + } + + /* Bring the inner IP header in the first mbuf, if not there already */ + if (m->m_len < hlen) + { + if ((m = m_pullup(m, hlen)) == 0) + { + DPRINTF(("ipip_input(): m_pullup() failed\n")); + ipipstat.ipips_hdrops++; + return; + } + } + + /* + * RFC 1853 specifies that the inner TTL should not be touched on + * decapsulation. There's no reason this comment should be here, but + * this is as good as any a position. + */ + + /* Some sanity checks in the inner IPv4 header */ + switch (v >> 4) + { +#ifdef INET + case 4: + ipo = mtod(m, struct ip *); + nxt = ipo->ip_p; + ip_ecn_egress(ECN_ALLOWED, &otos, &ipo->ip_tos); + break; +#endif /* INET */ + +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *) ipo; + nxt = ip6->ip6_nxt; + itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; + ip_ecn_egress(ECN_ALLOWED, &otos, &itos); + ip6->ip6_flow &= ~htonl(0xff << 20); + ip6->ip6_flow |= htonl((u_int32_t) itos << 20); + break; +#endif + } + + /* Check for local address spoofing. */ + if (m->m_pkthdr.rcvif == NULL || + !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) + { + for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) + { + for (ifa = ifp->if_addrlist.tqh_first; + ifa != 0; + ifa = ifa->ifa_list.tqe_next) + { +#ifdef INET + if (ipo) + { + if (ifa->ifa_addr->sa_family != AF_INET) + continue; + + sin = (struct sockaddr_in *) ifa->ifa_addr; + + if (sin->sin_addr.s_addr == ipo->ip_src.s_addr) + { + DPRINTF(("ipip_input(): possible local address spoofing detected on packet from %s to %s (%s->%s)\n", inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst), inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst))); + ipipstat.ipips_spoof++; + m_freem(m); + return; + } + } +#endif /* INET */ + +#ifdef INET6 + if (ip6) + { + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + + sin6 = (struct sockaddr_in6 *) ifa->ifa_addr; + + if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) + { + DPRINTF(("ipip_input(): possible local address spoofing detected on packet\n")); + m_freem(m); + return; + } + + } +#endif /* INET6 */ + } + } + } + + /* Statistics */ + ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen; + + /* tdbi is only set in ESP or AH, if the next protocol is UDP or TCP */ + if (m->m_flags & (M_CONF|M_AUTH)) + m->m_pkthdr.tdbi = NULL; + + /* + * Interface pointer stays the same; if no IPsec processing has + * been done (or will be done), this will point to a normal + * interface. Otherwise, it'll point to an enc interface, which + * will allow a packet filter to distinguish between secure and + * untrusted packets. + */ + +#ifdef INET + if (ipo) + { + ifq = &ipintrq; + isr = NETISR_IP; + } +#endif /* INET */ + +#ifdef INET6 + if (ip6) + { + ifq = &ip6intrq; + isr = NETISR_IPV6; + } +#endif /* INET6 */ + + s = splimp(); /* isn't it already? */ + if (IF_QFULL(ifq)) + { + IF_DROP(ifq); + m_freem(m); + ipipstat.ipips_qfull++; + + splx(s); + + DPRINTF(("ipip_input(): packet dropped because of full queue\n")); + return; + } + + IF_ENQUEUE(ifq, m); + schednetisr(isr); + splx(s); + + return; +} + +int +ipip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, + int protoff) +{ + u_int8_t tp, otos; + +#ifdef INET + u_int8_t itos; + struct ip *ipo; +#endif /* INET */ + +#ifdef INET6 + struct ip6_hdr *ip6o; +#endif /* INET6 */ + + /* Deal with empty TDB source/destination addresses */ + /* XXX */ + + m_copydata(m, 0, 1, &tp); + tp = (tp >> 4) & 0xff; /* Get the IP version number */ + + switch (tdb->tdb_dst.sa.sa_family) + { +#ifdef INET + case AF_INET: + if ((tdb->tdb_src.sa.sa_family != AF_INET) || + (tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY) || + (tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY)) + { + DPRINTF(("ipip_output(): unspecified tunnel endpoind address in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); + ipipstat.ipips_unspec++; + m_freem(m); + *mp = NULL; + return EINVAL; + } + + M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); + if (m == 0) + { + DPRINTF(("ipip_output(): M_PREPEND failed\n")); + ipipstat.ipips_hdrops++; + *mp = NULL; + return ENOBUFS; + } + + ipo = mtod(m, struct ip *); + + ipo->ip_v = IPVERSION; + ipo->ip_hl = 5; + ipo->ip_len = htons(m->m_pkthdr.len); + ipo->ip_ttl = ip_defttl; + ipo->ip_sum = 0; + ipo->ip_src = tdb->tdb_src.sin.sin_addr; + ipo->ip_dst = tdb->tdb_dst.sin.sin_addr; + + /* + * We do the htons() to prevent snoopers from determining our + * endianness. + */ + ipo->ip_id = htons(ip_randomid()); + + /* If the inner protocol is IP */ + if (tp == IPVERSION) + { + /* Save ECN notification */ + m_copydata(m, sizeof(struct ip) + offsetof(struct ip, ip_tos), + sizeof(u_int8_t), (caddr_t) &itos); + + ipo->ip_p = IPPROTO_IPIP; + + /* + * We should be keeping tunnel soft-state and send back ICMPs + * if needed. + */ + m_copydata(m, sizeof(struct ip) + offsetof(struct ip, ip_off), + sizeof(u_int16_t), (caddr_t) &ipo->ip_off); + ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK); + } +#ifdef INET6 + else if (tp == (IPV6_VERSION >> 4)) + { + u_int32_t itos32; + /* Save ECN notification */ + m_copydata(m, sizeof(struct ip) + + offsetof(struct ip6_hdr, ip6_flow), + sizeof(u_int32_t), (caddr_t) &itos32); + itos = ntohl(itos32) >> 20; + + ipo->ip_p = IPPROTO_IPV6; + ipo->ip_off = 0; + } +#endif /* INET6 */ + else + { + m_freem(m); + *mp = NULL; + return EAFNOSUPPORT; + } + + otos = 0; + ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); + ipo->ip_tos = otos; + break; +#endif /* INET */ + +#ifdef INET6 + case AF_INET6: + if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) || + (tdb->tdb_src.sa.sa_family != AF_INET6) || + IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) + { + DPRINTF(("ipip_output(): unspecified tunnel endpoind address in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); + ipipstat.ipips_unspec++; + m_freem(m); + *mp = NULL; + return ENOBUFS; + } + + M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT); + if (m == 0) + { + DPRINTF(("ipip_output(): M_PREPEND failed\n")); + ipipstat.ipips_hdrops++; + *mp = NULL; + return ENOBUFS; + } + + /* Initialize IPv6 header */ + ip6o = mtod(m, struct ip6_hdr *); + ip6o->ip6_flow = 0; + ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; + ip6o->ip6_vfc |= IPV6_VERSION; + ip6o->ip6_plen = htons(m->m_pkthdr.len); + ip6o->ip6_hlim = ip_defttl; + ip6o->ip6_dst = tdb->tdb_dst.sin6.sin6_addr; + ip6o->ip6_src = tdb->tdb_src.sin6.sin6_addr; + +#ifdef INET + if (tp == IPVERSION) + { + /* Save ECN notification */ + m_copydata(m, sizeof(struct ip6_hdr) + + offsetof(struct ip, ip_tos), sizeof(u_int8_t), + (caddr_t) &itos); + + ip6o->ip6_nxt = IPPROTO_IPIP; /* This is really IPVERSION */ + } + else +#endif /* INET */ + if (tp == (IPV6_VERSION >> 4)) + { + u_int32_t itos32; + /* Save ECN notification */ + m_copydata(m, sizeof(struct ip6_hdr) + + offsetof(struct ip6_hdr, ip6_flow), + sizeof(u_int32_t), (caddr_t) &itos32); + itos = ntohl(itos32) >> 20; + + ip6o->ip6_nxt = IPPROTO_IPV6; + } + else + { + m_freem(m); + *mp = NULL; + return EAFNOSUPPORT; + } + + otos = 0; + ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); + ip6o->ip6_flow |= htonl((u_int32_t) otos << 20); + break; +#endif /* INET6 */ + + default: + DPRINTF(("ipip_output(): unsupported protocol family %d\n", + tdb->tdb_dst.sa.sa_family)); + m_freem(m); + *mp = NULL; + ipipstat.ipips_family++; + return ENOBUFS; + } + + ipipstat.ipips_opackets++; + + *mp = m; + +#ifdef INET + if (tdb->tdb_dst.sa.sa_family == AF_INET) + { + if (tdb->tdb_xform->xf_type == XF_IP4) + tdb->tdb_cur_bytes += m->m_pkthdr.len - sizeof(struct ip); + + ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip); + } +#endif /* INET */ + +#ifdef INET6 + if (tdb->tdb_dst.sa.sa_family == AF_INET6) + { + if (tdb->tdb_xform->xf_type == XF_IP4) + tdb->tdb_cur_bytes += m->m_pkthdr.len - sizeof(struct ip6_hdr); + + ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip6_hdr); + } +#endif /* INET6 */ + + return 0; +} + +#ifdef IPSEC + +int +ipe4_attach() +{ + return 0; +} + +int +ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) +{ + tdbp->tdb_xform = xsp; + return 0; +} + +int +ipe4_zeroize(struct tdb *tdbp) +{ + return 0; +} + +void +ipe4_input(struct mbuf *m, ...) +{ + /* This is a rather serious mistake, so no conditional printing */ + printf("ipe4_input(): should never be called\n"); + if (m) + m_freem(m); +} +#endif /* IPSEC */ + +int +ipip_sysctl(name, namelen, oldp, oldlenp, newp, newlen) + int *name; + u_int namelen; + void *oldp; + size_t *oldlenp; + void *newp; + size_t newlen; +{ + /* All sysctl names at this level are terminal. */ + if (namelen != 1) + return (ENOTDIR); + + switch (name[0]) { + case IPIPCTL_ALLOW: + return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow)); + default: + return (ENOPROTOOPT); + } + /* NOTREACHED */ +} diff --git a/sys/netinet/ip_ip4.h b/sys/netinet/ip_ipip.h index 5e15d9c4bdd..c413e139ca2 100644 --- a/sys/netinet/ip_ip4.h +++ b/sys/netinet/ip_ipip.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ip4.h,v 1.17 2000/01/13 05:03:45 angelos Exp $ */ +/* $OpenBSD: ip_ipip.h,v 1.1 2000/01/21 03:15:05 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -35,46 +35,46 @@ * PURPOSE. */ -#ifndef _NETINET_IP4_H_ -#define _NETINET_IP4_H_ +#ifndef _NETINET_IPIP_H_ +#define _NETINET_IPIP_H_ /* * IP-inside-IP processing. * Not quite all the functionality of RFC-1853, but the main idea is there. */ -struct ip4stat +struct ipipstat { - u_int32_t ip4s_ipackets; /* total input packets */ - u_int32_t ip4s_opackets; /* total output packets */ - u_int32_t ip4s_hdrops; /* packet shorter than header shows */ - u_int32_t ip4s_qfull; - u_int64_t ip4s_ibytes; - u_int64_t ip4s_obytes; - u_int32_t ip4s_pdrops; /* packet dropped due to policy */ - u_int32_t ip4s_spoof; /* IP spoofing attempts */ - u_int32_t ip4s_family; /* Protocol family mismatch */ - u_int32_t ip4s_unspec; /* Missing tunnel endpoint address */ + u_int32_t ipips_ipackets; /* total input packets */ + u_int32_t ipips_opackets; /* total output packets */ + u_int32_t ipips_hdrops; /* packet shorter than header shows */ + u_int32_t ipips_qfull; + u_int64_t ipips_ibytes; + u_int64_t ipips_obytes; + u_int32_t ipips_pdrops; /* packet dropped due to policy */ + u_int32_t ipips_spoof; /* IP spoofing attempts */ + u_int32_t ipips_family; /* Protocol family mismatch */ + u_int32_t ipips_unspec; /* Missing tunnel endpoint address */ }; #define IP4_DEFAULT_TTL 0 #define IP4_SAME_TTL -1 /* - * Names for IP4 sysctl objects + * Names for IPIP sysctl objects */ -#define IP4CTL_ALLOW 1 /* accept incoming IP4 packets */ -#define IP4CTL_MAXID 2 +#define IPIPCTL_ALLOW 1 /* accept incoming IP4 packets */ +#define IPIPCTL_MAXID 2 -#define IP4CTL_NAMES { \ +#define IPIPCTL_NAMES { \ { 0, 0 }, \ { "allow", CTLTYPE_INT }, \ } #ifdef _KERNEL -int ip4_sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); +int ipip_sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); -extern int ip4_allow; -extern struct ip4stat ip4stat; +extern int ipip_allow; +extern struct ipipstat ipipstat; #endif /* _KERNEL */ -#endif /* _NETINET_IP4_H_ */ +#endif /* _NETINET_IPIP_H_ */ diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index c57f4b8cff8..1cfa5c21bb4 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.75 2000/01/13 05:30:11 angelos Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.76 2000/01/21 03:15:05 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -139,7 +139,7 @@ struct xformsw xformsw[] = { { XF_IP4, 0, "IPv4 Simple Encapsulation", ipe4_attach, ipe4_init, ipe4_zeroize, (struct mbuf * (*)(struct mbuf *, struct tdb *, int, int))ipe4_input, - ipe4_output, }, + ipip_output, }, { XF_OLD_AH, XFT_AUTH, "Keyed Authentication, RFC 1828/1852", ah_old_attach, ah_old_init, ah_old_zeroize, ah_old_input, ah_old_output, }, @@ -1822,7 +1822,7 @@ ipsp_process_packet(struct mbuf *m, struct mbuf **mp, struct tdb *tdb, int *af, #endif /* INET6 */ /* Encapsulate -- the last two arguments are unused */ - error = ipe4_output(m, tdb, mp, 0, 0); + error = ipip_output(m, tdb, mp, 0, 0); if (((*mp) == NULL) && (!error)) error = EFAULT; if (error) diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 4d240bc2b8b..417b08970ef 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.58 2000/01/13 06:02:31 angelos Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.59 2000/01/21 03:15:05 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -547,9 +547,13 @@ extern struct flow *find_global_flow(union sockaddr_union *, extern int ipe4_attach(void); extern int ipe4_init(struct tdb *, struct xformsw *, struct ipsecinit *); extern int ipe4_zeroize(struct tdb *); -extern int ipe4_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); +extern int ipip_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); extern void ipe4_input __P((struct mbuf *, ...)); +extern void ipip_input __P((struct mbuf *, int)); + +#ifdef INET extern void ip4_input __P((struct mbuf *, ...)); +#endif /* INET */ #ifdef INET6 extern int ip4_input6 __P((struct mbuf **, int *, int)); diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 48850137865..b72172ad612 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_mroute.c,v 1.18 1999/08/08 15:04:22 niklas Exp $ */ +/* $OpenBSD: ip_mroute.c,v 1.19 2000/01/21 03:15:05 angelos Exp $ */ /* $NetBSD: ip_mroute.c,v 1.27 1996/05/07 02:40:50 thorpej Exp $ */ /* @@ -163,7 +163,7 @@ static vifi_t numvifs = 0; static int have_encap_tunnel = 0; /* - * one-back cache used by ipip_input to locate a tunnel's vif + * one-back cache used by ipip_mroute_input to locate a tunnel's vif * given a datagram's src ip address. */ static u_int32_t last_encap_src; @@ -565,7 +565,10 @@ add_vif(m) /* Prepare cached route entry. */ bzero(&vifp->v_route, sizeof(vifp->v_route)); - /* Tell ipip_input() to start looking at encapsulated packets. */ + /* + * Tell ipip_mroute_input() to start looking at + * encapsulated packets. + */ have_encap_tunnel = 1; } else { /* Use the physical interface associated with the address. */ @@ -1449,9 +1452,9 @@ encap_send(ip, vifp, m) */ void #if __STDC__ -ipip_input(struct mbuf *m, ...) +ipip_mroute_input(struct mbuf *m, ...) #else -ipip_input(m, va_alist) +ipip_mroute_input(m, va_alist) struct mbuf *m; va_dcl #endif diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h index feb51fc1a00..594e1804adc 100644 --- a/sys/netinet/ip_mroute.h +++ b/sys/netinet/ip_mroute.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_mroute.h,v 1.5 1999/12/08 06:50:20 itojun Exp $ */ +/* $OpenBSD: ip_mroute.h,v 1.6 2000/01/21 03:15:05 angelos Exp $ */ /* $NetBSD: ip_mroute.h,v 1.10 1996/02/13 23:42:55 christos Exp $ */ /* @@ -230,6 +230,6 @@ void rsvp_input __P((struct mbuf *, int, int)); #else int ip_mforward __P((struct mbuf *, struct ifnet *)); #endif -void ipip_input __P((struct mbuf *, ...)); +void ipip_mroute_input __P((struct mbuf *, ...)); #endif /* _KERNEL */ diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 65845c93ad5..dba946b8b42 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_gif.c,v 1.4 2000/01/12 06:35:04 angelos Exp $ */ +/* $OpenBSD: in6_gif.c,v 1.5 2000/01/21 03:15:06 angelos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -101,7 +101,7 @@ in6_gif_output(ifp, family, m, rt) return ENETUNREACH; } - /* setup dummy tdb. it highly depends on ipe4_output() code. */ + /* setup dummy tdb. it highly depends on ipip_output() code. */ bzero(&tdb, sizeof(tdb)); bzero(&xfs, sizeof(xfs)); tdb.tdb_src.sin6.sin6_family = AF_INET6; @@ -146,7 +146,7 @@ in6_gif_output(ifp, family, m, rt) /* encapsulate into IPv6 packet */ mp = NULL; - error = ipe4_output(m, &tdb, &mp, hlen, poff); + error = ipip_output(m, &tdb, &mp, hlen, poff); if (error) return error; else if (mp == NULL) @@ -224,10 +224,14 @@ int in6_gif_input(mp, offp, proto) } } - if (gifp && (m->m_flags & (M_AUTH | M_CONF)) == 0) + if (gifp) { m->m_pkthdr.rcvif = gifp; + ipip_input(m, *offp); + return IPPROTO_DONE; + } inject: - ip4_input(m, *offp); + /* No GIF tunnel configured */ + ip4_input6(&m, offp, 0); /* XXX last argument ignored */ return IPPROTO_DONE; } diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index b0160854045..1cb08c6c6b3 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_proto.c,v 1.13 2000/01/13 06:01:22 angelos Exp $ */ +/* $OpenBSD: in6_proto.c,v 1.14 2000/01/21 03:15:06 angelos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -93,7 +93,7 @@ #include <netinet/ip_ipsp.h> #include <netinet/ip_ah.h> #include <netinet/ip_esp.h> -#include <netinet/ip_ip4.h> +#include <netinet/ip_ipip.h> #include <netinet6/pim6_var.h> @@ -197,31 +197,31 @@ struct ip6protosw inet6sw[] = { #endif /* 0 */ #endif /* IPSEC */ #if NGIF > 0 -{ SOCK_RAW, &inet6domain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR, +{ SOCK_RAW, &inet6domain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, in6_gif_input,0, 0, 0, 0, 0, 0, 0, 0, }, -#ifdef INET6 +#ifdef INET { SOCK_RAW, &inet6domain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, in6_gif_input,0, 0, 0, 0, 0, 0, 0, 0, }, -#endif /* INET6 */ +#endif /* INET */ #else /* NFIG */ -{ SOCK_RAW, &inet6domain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR, +{ SOCK_RAW, &inet6domain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, ip4_input6, rip6_output, 0, rip6_ctloutput, rip6_usrreq, /* XXX */ - 0, 0, 0, 0, ip4_sysctl + 0, 0, 0, 0, ipip_sysctl }, -#ifdef INET6 -{ SOCK_RAW, &inet6domain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, - ip4_input6, rip6_output, 0, rip6_ctloutput, +#ifdef INET +{ SOCK_RAW, &inet6domain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR, + ip4_input, rip6_output, 0, rip6_ctloutput, 0, 0, 0, 0, 0, }, -#endif /* INET6 */ +#endif /* INET */ #endif /* GIF */ { SOCK_RAW, &inet6domain, IPPROTO_PIM, PR_ATOMIC|PR_ADDR, pim6_input, rip6_output, 0, rip6_ctloutput, |