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.