summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_ip4.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_ip4.c')
-rw-r--r--sys/netinet/ip_ip4.c151
1 files changed, 113 insertions, 38 deletions
diff --git a/sys/netinet/ip_ip4.c b/sys/netinet/ip_ip4.c
index b715b9c508a..0438ec05400 100644
--- a/sys/netinet/ip_ip4.c
+++ b/sys/netinet/ip_ip4.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ip4.c,v 1.33 1999/10/29 02:02:33 angelos Exp $ */
+/* $OpenBSD: ip_ip4.c,v 1.34 1999/12/06 07:14:36 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -69,6 +69,14 @@
#include <netinet/ip_mroute.h>
#endif
+#ifdef INET6
+#include <netinet6/in6.h>
+#include <netinet6/ip6.h>
+#include <netinet6/in6_pcb.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/icmp6.h>
+#endif /* INET6 */
+
#include <sys/socketvar.h>
#include <net/raw_cb.h>
@@ -106,15 +114,19 @@ ip4_input(m, va_alist)
va_dcl
#endif
{
+ register struct sockaddr_in *sin;
register struct ifnet *ifp;
register struct ifaddr *ifa;
- register struct sockaddr_in *sin;
- int iphlen;
- struct ip *ipo, *ipi;
struct ifqueue *ifq = NULL;
- int s;
+ struct ip *ipo, *ipi;
+ int s, iphlen;
va_list ap;
+#ifdef INET6
+ register struct sockaddr_in6 *sin6;
+ struct ip6_hdr *ipv6;
+#endif /* INET6 */
+
va_start(ap, m);
iphlen = va_arg(ap, int);
va_end(ap);
@@ -171,34 +183,56 @@ ip4_input(m, va_alist)
ipo = mtod(m, struct ip *);
}
- ipi = (struct ip *) ((caddr_t) ipo + iphlen);
-
/*
* 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.
*/
- if (ipi->ip_v != IPVERSION)
+ if (ipo->ip_p == IPPROTO_IPIP)
{
- DPRINTF(("ip4_input(): wrong version %d on packet from %s to %s (%s->%s)\n", ipi->ip_v, inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst), inet_ntoa4(ipi->ip_src), inet_ntoa4(ipi->ip_dst)));
- ip4stat.ip4s_notip4++;
- m_freem(m);
- return;
- }
+ ipi = (struct ip *) ((caddr_t) ipo + iphlen);
- /*
- * If we do not accept IP4 other than part of ESP & AH, we should
- * not accept a packet with double ip4 headers neither.
- */
+ if (ipi->ip_v != IPVERSION)
+ {
+ DPRINTF(("ip4_input(): wrong version %d on packet from %s to %s (%s->%s)\n", ipi->ip_v, inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst), inet_ntoa4(ipi->ip_src), inet_ntoa4(ipi->ip_dst)));
+ ip4stat.ip4s_notip4++;
+ m_freem(m);
+ return;
+ }
+
+ /*
+ * If we do not accept IP4 other than as part of ESP & AH, we should
+ * not accept a packet with double ip4 headers neither.
+ */
- if (!ip4_allow && ipi->ip_p == IPPROTO_IPIP)
+ if (!ip4_allow &&
+ ((ipi->ip_p == IPPROTO_IPIP) ||
+ (ipi->ip_p == IPPROTO_IPV6)))
+ {
+ DPRINTF(("ip4_input(): dropped due to policy\n"));
+ ip4stat.ip4s_pdrops++;
+ m_freem(m);
+ return;
+ }
+ }
+
+#ifdef INET6
+ if (ipo->ip_p == IPPROTO_IPIP)
{
- DPRINTF(("ip4_input(): dropped due to policy\n"));
- ip4stat.ip4s_pdrops++;
- m_freem(m);
- return;
+ ipv6 = (struct ip6_hdr *) ((caddr_t) ipo + iphlen);
+
+ if (ipv6->ip6_vfc != IPV6_VERSION)
+ {
+ DPRINTF(("ip4_input(): wrong version %d on packet from %s to %s (%s->%s)\n", ipi->ip_v, inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst), inet6_ntoa4(ipv6->ip6_src), inet6_ntoa4(ipv6->ip6_dst)));
+ ip4stat.ip4s_notip4++;
+ m_freem(m);
+ return;
+ }
+
+ /* XXX Do we need to check that we don't have double-headers ? */
}
+#endif /* INET6 */
/*
* Check remote packets for local address spoofing.
@@ -212,23 +246,57 @@ ip4_input(m, va_alist)
ifa != 0;
ifa = ifa->ifa_list.tqe_next)
{
- if (ifa->ifa_addr->sa_family != AF_INET)
- continue;
-
- sin = (struct sockaddr_in *) ifa->ifa_addr;
-
- if (sin->sin_addr.s_addr == ipi->ip_src.s_addr)
+ switch (ipo->ip_p)
{
- DPRINTF(("ip_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(ipi->ip_src), inet_ntoa4(ipi->ip_dst)));
- ip4stat.ip4s_spoof++;
- m_freem(m);
- return;
+ case IPPROTO_IPIP:
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ sin = (struct sockaddr_in *) ifa->ifa_addr;
+
+ if (sin->sin_addr.s_addr == ipi->ip_src.s_addr)
+ {
+ DPRINTF(("ip_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(ipi->ip_src), inet_ntoa4(ipi->ip_dst)));
+ ip4stat.ip4s_spoof++;
+ m_freem(m);
+ return;
+ }
+
+ break;
+
+#ifdef INET6
+ case IPPROTO_IPV6:
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+
+ sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
+
+ if (!bcmp(&sin6->sin6_addr, &ipv6->sin6_addr,
+ sizeof(struct in6_addr)))
+ {
+ DPRINTF(("ip_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), inet6_ntoa4(ipv6->ip6_src), inet6_ntoa4(ipv6->ip6_dst)));
+ ip4stat.ip4s_spoof++;
+ m_freem(m);
+ return;
+ }
+
+ break;
+#endif /* INET6 */
}
+
}
}
/* Statistics */
- ip4stat.ip4s_ibytes += ntohs(ipi->ip_len);
+ ip4stat.ip4s_ibytes += m->m_pkthdr.len - iphlen;
+
+ /* Determine whether we need to queue in IPv4 or IPv6 input queue */
+ ifq = &ipintrq;
+
+#ifdef INET6
+ if (ipo->ip_p == IPPROTO_IPV6)
+ ifq = &ip6intrq;
+#endif
/*
* Interface pointer is already in first mbuf; chop off the
@@ -239,7 +307,7 @@ ip4_input(m, va_alist)
m->m_pkthdr.len -= iphlen;
m->m_data += iphlen;
- /* tdbi is only set in esp or ah, if next protocol is udp or tcp */
+ /* 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;
@@ -251,8 +319,6 @@ ip4_input(m, va_alist)
* untrusted packets.
*/
- ifq = &ipintrq;
-
s = splimp(); /* isn't it already? */
if (IF_QFULL(ifq))
{
@@ -266,14 +332,23 @@ ip4_input(m, va_alist)
}
IF_ENQUEUE(ifq, m);
- schednetisr(NETISR_IP);
+
+ if (ifq == &ipintrq)
+ schednetisr(NETISR_IP);
+
+#ifdef INET6
+ if (ifq == &ip6intrq)
+ schednetisr(NETISR_IP6);
+#endif /* INET6 */
+
splx(s);
return;
}
#ifdef IPSEC
int
-ipe4_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp)
+ipe4_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
+ int protoff)
{
struct ip *ipo, *ipi;
ushort ilen;