summaryrefslogtreecommitdiff
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 1125455c384c..97dc239fee09 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -666,6 +666,32 @@ reply:
(void)memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha));
(void)memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha));
rtfree(rt);
+
+ /*
+ * Also check that the node which sent the ARP packet
+ * is on the the interface we expect it to be on. This
+ * avoids ARP chaos if an interface is connected to the
+ * wrong network.
+ */
+ sin.sin_addr = isaddr;
+
+ rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL);
+ if (!rt) {
+ m_freem(m);
+ return;
+ }
+ if (rt->rt_ifp != &ac->ac_if) {
+ log(LOG_INFO, "arp_proxy: ignoring request"
+ " from %s via %s%d, expecting %s%d\n",
+ inet_ntoa(isaddr), ac->ac_if.if_name,
+ ac->ac_if.if_unit, rt->rt_ifp->if_name,
+ rt->rt_ifp->if_unit);
+ rtfree(rt);
+ m_freem(m);
+ return;
+ }
+ rtfree(rt);
+
#ifdef DEBUG_PROXY
printf("arp: proxying for %s\n",
inet_ntoa(itaddr));