aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6/ip6_input.c
diff options
context:
space:
mode:
authorHajimu UMEMOTO <ume@FreeBSD.org>2001-04-19 23:51:20 +0000
committerHajimu UMEMOTO <ume@FreeBSD.org>2001-04-19 23:51:20 +0000
commit8d642984071b96be35e83c59b6e41d9a3de4ae1a (patch)
tree7f41039c303f035a96b3e3d58eaf05e803401534 /sys/netinet6/ip6_input.c
parentc612c69dc759555832a8594f5a9761332da5b757 (diff)
downloadsrc-8d642984071b96be35e83c59b6e41d9a3de4ae1a.tar.gz
src-8d642984071b96be35e83c59b6e41d9a3de4ae1a.zip
- Fix to receive icmp6 echo reply within the host itself to ff02::1.
- Fix to receive icmp6 echo reply to link-local of itself. Reported by: Eriya Akasaka <eakasaka@rodfbs.org> Submitted by: JINMEI Tatuya <jinmei@isl.rdc.toshiba.co.jp>
Notes
Notes: svn path=/head/; revision=75719
Diffstat (limited to 'sys/netinet6/ip6_input.c')
-rw-r--r--sys/netinet6/ip6_input.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index b1de716dd049..b63d4bf0281b 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -439,8 +439,39 @@ ip6_input(m)
if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0) {
if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) {
struct in6_ifaddr *ia6;
+#ifndef FAKE_LOOPBACK_IF
+ int deliverifid;
- if ((ia6 = in6ifa_ifpwithaddr(m->m_pkthdr.rcvif,
+ /*
+ * Get a "real" delivered interface, which should be
+ * embedded in the second 16 bits of the destination
+ * address. We can probably trust the value, but we
+ * add validation for the value just for safety.
+ */
+ deliverifid = ntohs(ip6->ip6_dst.s6_addr16[1]);
+ if (deliverifid > 0 && deliverifid <= if_index) {
+ deliverifp = ifindex2ifnet[deliverifid];
+
+ /*
+ * XXX: fake the rcvif to the real interface.
+ * Since m_pkthdr.rcvif should be lo0 (or a
+ * variant), it would confuse scope handling
+ * code later.
+ */
+ m->m_pkthdr.rcvif = deliverifp;
+ }
+ else {
+ /*
+ * Last resort; just use rcvif.
+ * XXX: the packet would be discarded by the
+ * succeeding check.
+ */
+ deliverifp = m->m_pkthdr.rcvif;
+ }
+#else
+ deliverifp = m->m_pkthdr.rcvif;
+#endif
+ if ((ia6 = in6ifa_ifpwithaddr(deliverifp,
&ip6->ip6_dst)) != NULL) {
ia6->ia_ifa.if_ipackets++;
ia6->ia_ifa.if_ibytes += m->m_pkthdr.len;
@@ -453,7 +484,6 @@ ip6_input(m)
goto bad;
}
ours = 1;
- deliverifp = m->m_pkthdr.rcvif;
goto hbhcheck;
}
}