* Improve error checking for arp messages.
* Clean stale headers from if_ether.c. Reported by: rozhuk.im at gmail.com Reviewed by: ae MFC after: 2 weeks
This commit is contained in:
parent
7b6660c9aa
commit
deb6bda6e3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287779
@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/if_llc.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/route.h>
|
||||
#include <net/vnet.h>
|
||||
@ -71,9 +70,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/ip_carp.h>
|
||||
#endif
|
||||
|
||||
#include <net/if_arc.h>
|
||||
#include <net/iso88025.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
#define SIN(s) ((const struct sockaddr_in *)(s))
|
||||
@ -529,6 +525,8 @@ static void
|
||||
arpintr(struct mbuf *m)
|
||||
{
|
||||
struct arphdr *ar;
|
||||
char *layer;
|
||||
int hlen;
|
||||
|
||||
if (m->m_len < sizeof(struct arphdr) &&
|
||||
((m = m_pullup(m, sizeof(struct arphdr))) == NULL)) {
|
||||
@ -537,26 +535,56 @@ arpintr(struct mbuf *m)
|
||||
}
|
||||
ar = mtod(m, struct arphdr *);
|
||||
|
||||
if (ntohs(ar->ar_hrd) != ARPHRD_ETHER &&
|
||||
ntohs(ar->ar_hrd) != ARPHRD_IEEE802 &&
|
||||
ntohs(ar->ar_hrd) != ARPHRD_ARCNET &&
|
||||
ntohs(ar->ar_hrd) != ARPHRD_IEEE1394 &&
|
||||
ntohs(ar->ar_hrd) != ARPHRD_INFINIBAND) {
|
||||
log(LOG_NOTICE, "arp: unknown hardware address format (0x%2D)"
|
||||
" (from %*D to %*D)\n", (unsigned char *)&ar->ar_hrd, "",
|
||||
ETHER_ADDR_LEN, (u_char *)ar_sha(ar), ":",
|
||||
ETHER_ADDR_LEN, (u_char *)ar_tha(ar), ":");
|
||||
/* Check if length is sufficient */
|
||||
if ((m = m_pullup(m, arphdr_len(ar))) == NULL) {
|
||||
log(LOG_NOTICE, "arp: short header received\n");
|
||||
return;
|
||||
}
|
||||
ar = mtod(m, struct arphdr *);
|
||||
|
||||
hlen = 0;
|
||||
layer = "";
|
||||
switch (ntohs(ar->ar_hrd)) {
|
||||
case ARPHRD_ETHER:
|
||||
hlen = ETHER_ADDR_LEN; /* RFC 826 */
|
||||
layer = "ethernet";
|
||||
break;
|
||||
case ARPHRD_IEEE802:
|
||||
hlen = 6; /* RFC 1390, FDDI_ADDR_LEN */
|
||||
layer = "fddi";
|
||||
break;
|
||||
case ARPHRD_ARCNET:
|
||||
hlen = 1; /* RFC 1201, ARC_ADDR_LEN */
|
||||
layer = "arcnet";
|
||||
break;
|
||||
case ARPHRD_INFINIBAND:
|
||||
hlen = 20; /* RFC 4391, INFINIBAND_ALEN */
|
||||
layer = "infiniband";
|
||||
break;
|
||||
case ARPHRD_IEEE1394:
|
||||
hlen = 0; /* SHALL be 16 */ /* RFC 2734 */
|
||||
layer = "firewire";
|
||||
|
||||
/*
|
||||
* Restrict too long harware addresses.
|
||||
* Currently we are capable of handling 20-byte
|
||||
* addresses ( sizeof(lle->ll_addr) )
|
||||
*/
|
||||
if (ar->ar_hln >= 20)
|
||||
hlen = 16;
|
||||
break;
|
||||
default:
|
||||
log(LOG_NOTICE, "arp: unknown hardware address format (0x%2d)\n",
|
||||
htons(ar->ar_hrd));
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m->m_len < arphdr_len(ar)) {
|
||||
if ((m = m_pullup(m, arphdr_len(ar))) == NULL) {
|
||||
log(LOG_NOTICE, "arp: runt packet\n");
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
ar = mtod(m, struct arphdr *);
|
||||
if (hlen != 0 && hlen != ar->ar_hln) {
|
||||
log(LOG_NOTICE, "arp: bad %s header length: %d\n", layer,
|
||||
ar->ar_hln);
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
ARPSTAT_INC(received);
|
||||
|
Loading…
Reference in New Issue
Block a user