summaryrefslogtreecommitdiffstats
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.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index df05c04..569047e 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -531,6 +531,21 @@ in_arpinput(struct mbuf *m)
}
ah = mtod(m, struct arphdr *);
+ /*
+ * ARP is only for IPv4 so we can reject packets with
+ * a protocol length not equal to an IPv4 address.
+ */
+ if (ah->ar_pln != sizeof(struct in_addr)) {
+ log(LOG_ERR, "in_arp: requested protocol length != %zu\n",
+ sizeof(struct in_addr));
+ return;
+ }
+
+ if (ETHER_IS_MULTICAST(ar_sha(ah))) {
+ log(LOG_ERR, "in_arp: source hardware address is multicast.");
+ return;
+ }
+
op = ntohs(ah->ar_op);
(void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
(void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
@@ -549,7 +564,7 @@ in_arpinput(struct mbuf *m)
*/
IN_IFADDR_RLOCK();
LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
- if (((bridged && ia->ia_ifp->if_bridge != NULL) ||
+ if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
ia->ia_ifp == ifp) &&
itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) {
ifa_ref(&ia->ia_ifa);
@@ -566,7 +581,7 @@ in_arpinput(struct mbuf *m)
}
}
LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
- if (((bridged && ia->ia_ifp->if_bridge != NULL) ||
+ if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
ia->ia_ifp == ifp) &&
isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) {
ifa_ref(&ia->ia_ifa);
@@ -702,7 +717,7 @@ match:
"arp from %*D: addr len: new %d, i/f %d (ignored)",
ifp->if_addrlen, (u_char *) ar_sha(ah), ":",
ah->ar_hln, ifp->if_addrlen);
- goto reply;
+ goto drop;
}
(void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
la->la_flags |= LLE_VALID;
@@ -731,18 +746,18 @@ match:
if (la->la_hold != NULL) {
struct mbuf *m_hold, *m_hold_next;
+ m_hold = la->la_hold;
+ la->la_hold = NULL;
+ la->la_numheld = 0;
memcpy(&sa, L3_ADDR(la), sizeof(sa));
LLE_WUNLOCK(la);
- for (m_hold = la->la_hold, la->la_hold = NULL;
- m_hold != NULL; m_hold = m_hold_next) {
+ for (; m_hold != NULL; m_hold = m_hold_next) {
m_hold_next = m_hold->m_nextpkt;
m_hold->m_nextpkt = NULL;
(*ifp->if_output)(ifp, m_hold, &sa, NULL);
}
} else
LLE_WUNLOCK(la);
- la->la_hold = NULL;
- la->la_numheld = 0;
} /* end of FIB loop */
reply:
if (op != ARPOP_REQUEST)
OpenPOWER on IntegriCloud