summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_icmp.c')
-rw-r--r--sys/netinet/ip_icmp.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 2ac0a8809e0..797b6d6ca32 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.124 2014/09/14 14:17:26 jsg Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.125 2014/09/30 08:26:15 mpi Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -686,9 +686,11 @@ int
icmp_reflect(struct mbuf *m, struct mbuf **op, struct in_ifaddr *ia)
{
struct ip *ip = mtod(m, struct ip *);
- struct in_addr t;
struct mbuf *opts = 0;
+ struct sockaddr_in sin;
+ struct rtentry *rt;
int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
+ u_int rtableid;
if (!in_canforward(ip->ip_src) &&
((ip->ip_src.s_addr & IN_CLASSA_NET) !=
@@ -700,58 +702,53 @@ icmp_reflect(struct mbuf *m, struct mbuf **op, struct in_ifaddr *ia)
#if NPF > 0
pf_pkt_addr_changed(m);
#endif
- t = ip->ip_dst;
- ip->ip_dst = ip->ip_src;
+ rtableid = m->m_pkthdr.ph_rtableid;
+
/*
* If the incoming packet was addressed directly to us,
* use dst as the src for the reply. For broadcast, use
* the address which corresponds to the incoming interface.
*/
if (ia == NULL) {
- TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
- if (ia->ia_ifp->if_rdomain !=
- rtable_l2(m->m_pkthdr.ph_rtableid))
- continue;
- if (t.s_addr == ia->ia_addr.sin_addr.s_addr)
- break;
- if ((ia->ia_ifp->if_flags & IFF_BROADCAST) &&
- ia->ia_broadaddr.sin_addr.s_addr != 0 &&
- t.s_addr == ia->ia_broadaddr.sin_addr.s_addr)
- break;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr = ip->ip_dst;
+
+ rt = rtalloc1(sintosa(&sin), 0, rtableid);
+ if (rt != NULL) {
+ if (rt->rt_flags & (RTF_LOCAL|RTF_BROADCAST))
+ ia = ifatoia(rt->rt_ifa);
+ rtfree(rt);
}
}
+
/*
* The following happens if the packet was not addressed to us.
* Use the new source address and do a route lookup. If it fails
* drop the packet as there is no path to the host.
*/
if (ia == NULL) {
- struct sockaddr_in *dst;
- struct route ro;
-
- memset(&ro, 0, sizeof(ro));
- ro.ro_tableid = m->m_pkthdr.ph_rtableid;
- dst = satosin(&ro.ro_dst);
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr = ip->ip_src;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr = ip->ip_src;
/* keep packet in the original virtual instance */
- ro.ro_rt = rtalloc1(&ro.ro_dst, RT_REPORT,
- m->m_pkthdr.ph_rtableid);
- if (ro.ro_rt == 0) {
+ rt = rtalloc1(sintosa(&sin), RT_REPORT, rtableid);
+ if (rt == NULL) {
ipstat.ips_noroute++;
m_freem(m);
return (EHOSTUNREACH);
}
- ia = ifatoia(ro.ro_rt->rt_ifa);
- ro.ro_rt->rt_use++;
- RTFREE(ro.ro_rt);
+ ia = ifatoia(rt->rt_ifa);
+ rt->rt_use++;
+ rtfree(rt);
}
- t = ia->ia_addr.sin_addr;
- ip->ip_src = t;
+ ip->ip_dst = ip->ip_src;
+ ip->ip_src = ia->ia_addr.sin_addr;
ip->ip_ttl = MAXTTL;
if (optlen > 0) {