Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys/netinet6 Pull up revision 1.55 (partial, via patch, ...
details: https://anonhg.NetBSD.org/src/rev/71a36cebb8bf
branches: netbsd-1-5
changeset: 491458:71a36cebb8bf
user: he <he%NetBSD.org@localhost>
date: Sat Apr 28 06:55:46 2001 +0000
description:
Pull up revision 1.55 (partial, via patch, requested by itojun):
Correct source address selection in icmp6_reflect().
Fixes two problems: kernel may fail to send icmp6 messages, and
there would be a way for user programs to cause a panic.
diffstat:
sys/netinet6/icmp6.c | 54 +++++++++++++++++++++++++++++++++++++++------------
1 files changed, 41 insertions(+), 13 deletions(-)
diffs (102 lines):
diff -r 789cefe67703 -r 71a36cebb8bf sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c Fri Apr 27 11:13:38 2001 +0000
+++ b/sys/netinet6/icmp6.c Sat Apr 28 06:55:46 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: icmp6.c,v 1.33.2.11 2001/04/22 17:33:53 he Exp $ */
+/* $NetBSD: icmp6.c,v 1.33.2.12 2001/04/28 06:55:46 he Exp $ */
/* $KAME: icmp6.c,v 1.146 2000/10/01 12:37:20 itojun Exp $ */
/*
@@ -1715,6 +1715,7 @@
int plen;
int type, code;
struct ifnet *outif = NULL;
+ struct sockaddr_in6 sa6_src;
#ifdef COMPAT_RFC1885
int mtu = IPV6_MMTU;
struct sockaddr_in6 *sin6 = &icmp6_reflect_rt.ro_dst;
@@ -1732,6 +1733,10 @@
* If there are extra headers between IPv6 and ICMPv6, strip
* off that header first.
*/
+#ifdef DIAGNOSTIC
+ if (sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) > MHLEN)
+ panic("assumption failed in icmp6_reflect");
+#endif
if (off > sizeof(struct ip6_hdr)) {
size_t l;
struct ip6_hdr nip6;
@@ -1768,11 +1773,25 @@
ip6->ip6_dst = ip6->ip6_src;
/* XXX hack for link-local addresses */
- if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst))
+ if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst) && !ip6->ip6_dst.s6_addr16[1]) {
+ if (!m->m_pkthdr.rcvif)
+ goto bad;
ip6->ip6_dst.s6_addr16[1] =
htons(m->m_pkthdr.rcvif->if_index);
- if (IN6_IS_ADDR_LINKLOCAL(&t))
+ }
+ if (IN6_IS_ADDR_LINKLOCAL(&t) && !t.s6_addr16[1]) {
+ if (!m->m_pkthdr.rcvif)
+ goto bad;
t.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
+ }
+ bzero(&sa6_src, sizeof(sa6_src));
+ sa6_src.sin6_family = AF_INET6;
+ sa6_src.sin6_len = sizeof(sa6_src);
+ sa6_src.sin6_addr = ip6->ip6_dst;
+ if (IN6_IS_SCOPE_LINKLOCAL(&sa6_src.sin6_addr)) {
+ sa6_src.sin6_scope_id = ntohs(sa6_src.sin6_addr.s6_addr16[1]);
+ sa6_src.sin6_addr.s6_addr16[1] = 0;
+ }
#ifdef COMPAT_RFC1885
/*
@@ -1784,6 +1803,7 @@
if (icmp6_reflect_rt.ro_rt == 0 ||
! (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_dst))) {
if (icmp6_reflect_rt.ro_rt) {
+ RTFREE(icmp6_reflect_rt.ro_rt);
icmp6_reflect_rt.ro_rt = 0;
}
bzero(sin6, sizeof(*sin6));
@@ -1827,19 +1847,27 @@
src = &t;
}
- if (src == 0 && m->m_pkthdr.rcvif)
+ if (src == 0) {
+ int e;
+ struct route_in6 ro;
+
/*
* This case matches to multicasts, our anycast, or unicasts
- * that we do not own. Select a source address which has the
- * same scope.
- * XXX: for (non link-local) multicast addresses, this might
- * not be a good choice.
+ * that we do not own. Select a source address based on the
+ * source address of the erroneous packet.
*/
- if ((ia = in6_ifawithscope(m->m_pkthdr.rcvif, &t)) != 0)
- src = &IA6_SIN6(ia)->sin6_addr;
-
- if (src == 0)
- goto bad;
+ bzero(&ro, sizeof(ro));
+ src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e);
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt); /* XXX: we could use this */
+ if (src == NULL) {
+ log(LOG_DEBUG,
+ "icmp6_reflect: source can't be determined: "
+ "dst=%s, error=%d\n",
+ ip6_sprintf(&sa6_src.sin6_addr), e);
+ goto bad;
+ }
+ }
ip6->ip6_src = *src;
Home |
Main Index |
Thread Index |
Old Index