Module Name:    src
Committed By:   roy
Date:           Tue Nov 15 10:47:39 UTC 2022

Modified Files:
        src/sys/net: if_ethersubr.c
        src/sys/netinet: if_arp.c
        src/sys/sys: mbuf.h

Log Message:
arp: Validate ARP source hardware address matches Ethernet source

RFC 5227 section 1.1 states that for a DaD ARP probe the sender hardware
address must match the hardware address of the interface sending the
packet.

We can now verify this by checking the mbuf tag PACKET_TAG_ETHERNET_SRC.

This fixes an obsure issue where an old router was sending out bogus
ARP probes.

Thanks to Ryo Shimizu <r...@nerv.org> for the re-implementation.


To generate a diff of this commit:
cvs rdiff -u -r1.322 -r1.323 src/sys/net/if_ethersubr.c
cvs rdiff -u -r1.310 -r1.311 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.235 -r1.236 src/sys/sys/mbuf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.322 src/sys/net/if_ethersubr.c:1.323
--- src/sys/net/if_ethersubr.c:1.322	Tue Nov 15 09:14:28 2022
+++ src/sys/net/if_ethersubr.c	Tue Nov 15 10:47:39 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ethersubr.c,v 1.322 2022/11/15 09:14:28 roy Exp $	*/
+/*	$NetBSD: if_ethersubr.c,v 1.323 2022/11/15 10:47:39 roy Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.322 2022/11/15 09:14:28 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.323 2022/11/15 10:47:39 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -886,6 +886,19 @@ ether_input(struct ifnet *ifp, struct mb
 #endif
 	}
 
+	/* For ARP packets, store the source address so that
+	 * ARP DAD probes can be validated. */
+	if (etype == ETHERTYPE_ARP) {
+		struct m_tag *mtag;
+
+		mtag = m_tag_get(PACKET_TAG_ETHERNET_SRC, ETHER_ADDR_LEN,
+		    M_NOWAIT);
+		if (mtag != NULL) {
+			memcpy(mtag + 1, &eh->ether_shost, ETHER_ADDR_LEN);
+			m_tag_prepend(m, mtag);
+		}
+	}
+
 	/* Strip off the Ethernet header. */
 	m_adj(m, ehlen);
 

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.310 src/sys/netinet/if_arp.c:1.311
--- src/sys/netinet/if_arp.c:1.310	Tue Nov 15 09:15:43 2022
+++ src/sys/netinet/if_arp.c	Tue Nov 15 10:47:39 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.310 2022/11/15 09:15:43 roy Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.311 2022/11/15 10:47:39 roy Exp $	*/
 
 /*
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.310 2022/11/15 09:15:43 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.311 2022/11/15 10:47:39 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -932,6 +932,8 @@ again:
 
 	/*
 	 * DAD check, RFC 5227.
+	 * ARP sender hardware address must match the interface
+	 * address of the interface sending the packet.
 	 * Collision on sender address is always a duplicate.
 	 * Collision on target address is only a duplicate
 	 * IF the sender address is the null host (ie a DAD probe)
@@ -945,13 +947,19 @@ again:
 	     m->m_flags & M_BCAST &&
 	     ia->ia4_flags & (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED))))
 	{
-		struct sockaddr_dl sdl, *sdlp;
+		struct m_tag *mtag;
 
-		sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
-		    ifp->if_index, ifp->if_type,
-		    NULL, 0, ar_sha(ah), ah->ar_hln);
-		arp_dad_duplicated((struct ifaddr *)ia, sdlp);
-		goto out;
+		mtag = m_tag_find(m, PACKET_TAG_ETHERNET_SRC);
+		if (mtag == NULL || (ah->ar_hln == ETHER_ADDR_LEN &&
+		    memcmp(mtag + 1, ar_sha(ah), ah->ar_hln) == 0)) {
+			struct sockaddr_dl sdl, *sdlp;
+
+			sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
+			    ifp->if_index, ifp->if_type,
+			    NULL, 0, ar_sha(ah), ah->ar_hln);
+			arp_dad_duplicated((struct ifaddr *)ia, sdlp);
+			goto out;
+		}
 	}
 
 	/*

Index: src/sys/sys/mbuf.h
diff -u src/sys/sys/mbuf.h:1.235 src/sys/sys/mbuf.h:1.236
--- src/sys/sys/mbuf.h:1.235	Tue Nov 15 09:13:43 2022
+++ src/sys/sys/mbuf.h	Tue Nov 15 10:47:39 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: mbuf.h,v 1.235 2022/11/15 09:13:43 roy Exp $	*/
+/*	$NetBSD: mbuf.h,v 1.236 2022/11/15 10:47:39 roy Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
@@ -800,6 +800,7 @@ int	m_tag_copy_chain(struct mbuf *, stru
 					    */
 #define PACKET_TAG_MPLS			29 /* Indicate it's for MPLS */
 #define PACKET_TAG_SRCROUTE		30 /* IPv4 source routing */
+#define PACKET_TAG_ETHERNET_SRC		31 /* Ethernet source address */
 
 /*
  * Return the number of bytes in the mbuf chain, m.

Reply via email to