summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/if_ether.c56
1 files changed, 25 insertions, 31 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index d4c733daeef..747ac05cff6 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ether.c,v 1.233 2018/01/16 10:33:55 mpi Exp $ */
+/* $OpenBSD: if_ether.c,v 1.234 2018/03/13 16:42:22 bluhm Exp $ */
/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
/*
@@ -78,6 +78,7 @@ int arpt_prune = (5 * 60); /* walk list every 5 minutes */
int arpt_keep = (20 * 60); /* once resolved, cache for 20 minutes */
int arpt_down = 20; /* once declared down, don't send for 20 secs */
+struct mbuf *arppullup(struct mbuf *m);
void arpinvalidate(struct rtentry *);
void arptfree(struct rtentry *);
void arptimer(void *);
@@ -417,36 +418,46 @@ bad:
return (EINVAL);
}
-/*
- * Common length and type checks are done here,
- * then the protocol-specific routine is called.
- */
-void
-arpinput(struct ifnet *ifp, struct mbuf *m)
+struct mbuf *
+arppullup(struct mbuf *m)
{
struct arphdr *ar;
int len;
#ifdef DIAGNOSTIC
if ((m->m_flags & M_PKTHDR) == 0)
- panic("arpintr");
+ panic("arp without packet header");
#endif
len = sizeof(struct arphdr);
if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
- return;
+ return NULL;
ar = mtod(m, struct arphdr *);
if (ntohs(ar->ar_hrd) != ARPHRD_ETHER ||
- ntohs(ar->ar_pro) != ETHERTYPE_IP) {
+ ntohs(ar->ar_pro) != ETHERTYPE_IP ||
+ ar->ar_hln != ETHER_ADDR_LEN ||
+ ar->ar_pln != sizeof(struct in_addr)) {
m_freem(m);
- return;
+ return NULL;
}
len += 2 * (ar->ar_hln + ar->ar_pln);
if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
- return;
+ return NULL;
+
+ return m;
+}
+/*
+ * Common length and type checks are done here,
+ * then the protocol-specific routine is called.
+ */
+void
+arpinput(struct ifnet *ifp, struct mbuf *m)
+{
+ if ((m = arppullup(m)) == NULL)
+ return;
niq_enqueue(&arpinq, m);
}
@@ -787,26 +798,9 @@ arpproxy(struct in_addr in, unsigned int rtableid)
void
revarpinput(struct ifnet *ifp, struct mbuf *m)
{
- struct arphdr *ar;
-
- if (m->m_len < sizeof(struct arphdr))
- goto out;
- ar = mtod(m, struct arphdr *);
- if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
- goto out;
- if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
- goto out;
- switch (ntohs(ar->ar_pro)) {
-
- case ETHERTYPE_IP:
- in_revarpinput(ifp, m);
+ if ((m = arppullup(m)) == NULL)
return;
-
- default:
- break;
- }
-out:
- m_freem(m);
+ in_revarpinput(ifp, m);
}
/*