Subject: kern/5527: i82586 driver drops broadcasts when in promiscuous mode
To: None <gnats-bugs@gnats.netbsd.org>
From: None <stephen.ma@jtec.com.au>
List: netbsd-bugs
Date: 06/02/1998 18:40:07
>Number:         5527
>Category:       kern
>Synopsis:       i82586 driver drops broadcasts when in promiscuous mode
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jun  2 01:50:01 1998
>Last-Modified:
>Originator:     stephen.ma@jtec.com.au
>Organization:
	Ummm....
>Release:        NetBSD-current 980531
>Environment:
System: NetBSD whitewater.jtec.com.au 1.3E NetBSD 1.3E (WHITEWATER) #22: Tue Jun 2 15:39:55 EST 1998 stephen@whitewater.jtec.com.au:/usr/src/sys/arch/i386/compile/WHITEWATER i386
Ethernet card: Intel EtherExpress 16.

>Description:
This bug should only affect ethernet interfaces using the i82586.c driver. When
the driver is put into promiscuous mode (by doing tcpdump, say), the driver
stops passing broadcast packets up to the IP stack. In particular, ARP packets
destined for the affected machine are not replied to. Note though, that these
broadcast packets are received thru bpf.
>How-To-Repeat:
do "tcpdump arp" on the affected machine, go to another machine on the same
local ethernet, delete the affected machine's entry from the arp cache, and
try pinging the affected machine.
>Fix:
Well, the quickest way of fixing this is to have the driver pass up all
multicast packets when in promiscuous mode. It looks like the driver is trying
hard to avoid this, so a somewhat more acceptable alternative would be to
compare a packet's destination address against the broadcast address. The
following patch implements the former fix:

*** /v1/netbsd/src/sys/dev/ic/i82586.c	Sat Feb 28 23:18:20 1998
--- ./i82586.c	Tue Jun  2 15:38:51 1998
***************
*** 382,387 ****
--- 382,393 ----
  #if NBPFILTER > 0
  		*to_bpf = (ifp->if_bpf != 0);
  #endif
+ 		/*
+ 		 * If it's a multicast, accept and hand up to BPF
+ 		 */
+ 		if (eh->ether_dhost[0] & 1)
+ 			return (1);
+ 
  		/* If for us, accept and hand up to BPF */
  		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
  			return (1);

>Audit-Trail:
>Unformatted: