Subject: port-i386/99: if_ed, multicast & promiscuous mode bugs
To: None <gnats-admin>
From: None <he@rype.runit.sintef.no>
List: netbsd-bugs
Date: 01/25/1994 04:50:13
>Number:         99
>Category:       port-i386
>Synopsis:       promiscuous mode doesn't work with (relatively) new if_ed
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 25 04:50:08 1994
>Originator:     Havard Eidnes
>Organization:
SINTEF RUNIT
>Release:        NetBSD-current as of one or two weeks ago
>Environment:
Configured for MULTICAST
System: NetBSD rype.runit.sintef.no 0.9a RYPE#32 i386

>Description:
	Due to relatively recent changes in the if_ed driver to support 
	multicast, it has become impossible to use BPF and set promiscuous 
	mode. The reason is that the BPF code fiddles the interface flags 
	and then calls the interface SIOCSIFFLAGS ioctl, but the code there will
	only do something if the interface is either being taken up or down.

	The attached patch is an attempt at circumventing that problem,
	but it appears to have other unintended side effects.  In effect,
	it makes other programs stop receiving network I/O (?) and they
	will be unable to resume until the interface is taken out of
	promiscuous mode.  This most visibly affects tcpdump, where it will
	hang trying to tranlslate IP addresses to names via the DNS (run
	it with -n and it produces output just fine, confirming that 
	promiscuous mode has been turned on).

>How-To-Repeat:
	See above.
>Fix:
	Here is the patch which tries to make promiscuous mode work again.
	As said above, it appears to have undesireable side effects which
	I have been unable to find a solution to.

*** if_ed.c.old	Thu Jan 13 11:42:29 1994
--- if_ed.c	Fri Jan 21 20:48:30 1994
***************
*** 171,174 ****
--- 171,175 ----
  	u_char	rec_page_stop;	/* last page of RX ring-buffer */
  	u_char	next_packet;	/* pointer to next unread RX packet */
+ 	short	old_if_flags;	/* old value of corresponding if_flags */
  } ed_softc[NED];
  
***************
*** 1300,1303 ****
--- 1301,1307 ----
  	ifp->if_flags &= ~IFF_OACTIVE;
  
+ 	/* Remember for next SIOCSIFFLAGS ioctl */
+ 	sc->old_if_flags = ifp->if_flags;
+ 
  	/*
  	 * ...and attempt to start output
***************
*** 1930,1938 ****
  		} else {
  		/*
! 		 * If interface is marked up and it is stopped, then start it
  		 */
  			if ((ifp->if_flags & IFF_UP) &&
! 		    	    ((ifp->if_flags & IFF_RUNNING) == 0))
! 				ed_init(ifp->if_unit);
  		}
  		/*
--- 1934,1948 ----
  		} else {
  		/*
! 		 * If interface is marked up and it is either stopped or some
! 		 * some of the changeable flags changed, then (re)initialize 
! 		 * and (re)start it
  		 */
  			if ((ifp->if_flags & IFF_UP) &&
! 		    	    ((ifp->if_flags & IFF_RUNNING) == 0) ||
! 		    	     ((ifp->if_flags & ~IFF_CANTCHANGE) !=
! 		    	      (sc->old_if_flags & ~IFF_CANTCHANGE)))
! 			{
! 			 	ed_reset(ifp->if_unit);
! 			}
  		}
  		/*
>Audit-Trail:
>Unformatted:

------------------------------------------------------------------------------