diff options
author | Hajimu UMEMOTO <ume@FreeBSD.org> | 2001-04-19 23:51:20 +0000 |
---|---|---|
committer | Hajimu UMEMOTO <ume@FreeBSD.org> | 2001-04-19 23:51:20 +0000 |
commit | 8d642984071b96be35e83c59b6e41d9a3de4ae1a (patch) | |
tree | 7f41039c303f035a96b3e3d58eaf05e803401534 /sys/netinet6/ip6_input.c | |
parent | c612c69dc759555832a8594f5a9761332da5b757 (diff) | |
download | src-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.c | 34 |
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; } } |