diff options
author | bz <bz@FreeBSD.org> | 2009-06-23 22:08:55 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2009-06-23 22:08:55 +0000 |
commit | a8839212d25048d806814db571facbc74524f2ff (patch) | |
tree | 3a58d4c5cc129f8a6f67da930359091b3204e2b3 /sys/netinet6/icmp6.c | |
parent | 6438d166b7094064ec21ed778af3438294b17ed2 (diff) | |
download | FreeBSD-src-a8839212d25048d806814db571facbc74524f2ff.zip FreeBSD-src-a8839212d25048d806814db571facbc74524f2ff.tar.gz |
Make callers to in6_selectsrc() and in6_pcbladdr() pass in memory
to save the selected source address rather than returning an
unreferenced copy to a pointer that might long be gone by the
time we use the pointer for anything meaningful.
Asked for by: rwatson
Reviewed by: rwatson
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r-- | sys/netinet6/icmp6.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 786ddc2..3ecf386 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2080,7 +2080,7 @@ icmp6_reflect(struct mbuf *m, size_t off) int plen; int type, code; struct ifnet *outif = NULL; - struct in6_addr origdst, *src = NULL; + struct in6_addr origdst, src, *srcp = NULL; /* too short to reflect */ if (off < sizeof(struct ip6_hdr)) { @@ -2148,7 +2148,7 @@ icmp6_reflect(struct mbuf *m, size_t off) if ((ia = ip6_getdstifaddr(m))) { if (!(ia->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) - src = &ia->ia_addr.sin6_addr; + srcp = &ia->ia_addr.sin6_addr; } else { struct sockaddr_in6 d; @@ -2161,12 +2161,12 @@ icmp6_reflect(struct mbuf *m, size_t off) if (ia && !(ia->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) { - src = &ia->ia_addr.sin6_addr; + srcp = &ia->ia_addr.sin6_addr; } } } - if (src == NULL) { + if (srcp == NULL) { int e; struct sockaddr_in6 sin6; struct route_in6 ro; @@ -2182,10 +2182,10 @@ icmp6_reflect(struct mbuf *m, size_t off) sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */ bzero(&ro, sizeof(ro)); - src = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &e); + e = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &src); if (ro.ro_rt) RTFREE(ro.ro_rt); /* XXX: we could use this */ - if (src == NULL) { + if (e) { char ip6buf[INET6_ADDRSTRLEN]; nd6log((LOG_DEBUG, "icmp6_reflect: source can't be determined: " @@ -2193,9 +2193,10 @@ icmp6_reflect(struct mbuf *m, size_t off) ip6_sprintf(ip6buf, &sin6.sin6_addr), e)); goto bad; } + srcp = &src; } - ip6->ip6_src = *src; + ip6->ip6_src = *srcp; ip6->ip6_flow = 0; ip6->ip6_vfc &= ~IPV6_VERSION_MASK; ip6->ip6_vfc |= IPV6_VERSION; |