From: mycroft@hal.gnu.ai.mit.edu (Charles Hannum)
Newsgroups: comp.unix.bsd
Subject: [386BSD] NE/2000 and packet filter
Date: 30 Dec 1992 11:43:29 GMT
Organization: MIT Artificial Intelligence Lab
Distribution: world
NNTP-Posting-Host: hal.gnu.ai.mit.edu


Below are diffs to make the modified NE/2000 driver posted by Curt
Mayer work with the Berkeley packet filter.

There were a couple of problems with the filter itself, and with
`tcpdump'.  I will post diffs of both shortly (when I get this one last
bug fixed).

-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----
*** /src/386bsd/if_ne.c	Mon Dec 21 18:10:33 1992
--- if_ne.c	Tue Dec 29 20:35:19 1992
***************
*** 43,48 ****
--- 43,50 ----
   * receive bottom end totally rewritten by Curt Mayer, Dec 1992.
   * no longer loses back to back packets. 
   * note to driver writers: RTFM!
+  *
+  * hooks for packet filter added by Charles Hannum, 29DEC1992.
   */
  
  #include "ne.h"
***************
*** 75,80 ****
--- 77,88 ----
  #include "netns/ns_if.h"
  #endif
  
+ #include "bpfilter.h"
+ #if NBPFILTER > 0
+ #include "net/bpf.h"
+ #include "net/bpfdesc.h"
+ #endif
+ 
  #include "i386/isa/isa_device.h"
  #include "i386/isa/if_nereg.h"
  #include "i386/isa/icu.h"
***************
*** 104,109 ****
--- 112,120 ----
  #define	ns_addr	ns_ac.ac_enaddr		/* hardware Ethernet address */
  	int	ns_flags;
  #define	DSF_LOCK	1		/* block re-entering enstart */
+ #if NBPFILTER > 0
+ #define	DSF_ATTACHED	2
+ #endif
  	int	ns_oactive;
  	int	ns_mask;
  	struct	prhdr	ns_ph;		/* hardware header of incoming packet*/
***************
*** 113,118 ****
--- 124,130 ----
  	u_char	ns_rxend;		/* receiver buffer end */
  	short	ns_port;		/* i/o port base */
  	short	ns_mode;		/* word/byte mode */
+ 	caddr_t	ns_bpf;
  } ne_softc[NNE] ;
  #define	ENBUFSIZE	(sizeof(struct ether_header) + ETHERMTU + 2 + ETHER_MIN_LEN)
  
***************
*** 304,310 ****
  	ifp->if_unit = unit;
  	ifp->if_name = nedriver.name ;
  	ifp->if_mtu = ETHERMTU;
! 	printf (" ne%d, address %s", 
  		(ns->ns_mode & DSDC_WTS) ? 2000 : 1000,
  		ether_sprintf(ns->ns_addr)) ;
  	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
--- 316,322 ----
  	ifp->if_unit = unit;
  	ifp->if_name = nedriver.name ;
  	ifp->if_mtu = ETHERMTU;
! 	printf (" ne%d, address %s",
  		(ns->ns_mode & DSDC_WTS) ? 2000 : 1000,
  		ether_sprintf(ns->ns_addr)) ;
  	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
***************
*** 315,320 ****
--- 327,336 ----
  	ifp->if_reset = nereset;
  	ifp->if_watchdog = 0;
  	if_attach(ifp);
+ 
+ #if NBPFILTER > 0
+ 	ns->ns_flags &= ~DSF_ATTACHED;
+ #endif
  }
  
  /*
***************
*** 330,335 ****
--- 346,364 ----
  	int i; char *cp;
  	register nec = ns->ns_port;
  
+ #if NBPFILTER > 0
+ 	if ((ns->ns_flags & DSF_ATTACHED) == 0) {
+ 		bpfattach(&ns->ns_bpf, ifp, DLT_EN10MB,
+ 			  sizeof (struct ether_header));
+ 		ns->ns_flags |= DSF_ATTACHED;
+ 	}
+ #endif
+ 
+ #ifdef NEDEBUG
+ 	printf ("ne: initializing, promiscuous mode %s\n",
+ 		ns->ns_if.if_flags & IFF_PROMISC ? "on" : "off");
+ #endif
+ 
   	if (ifp->if_addrlist == (struct ifaddr *)0) return;
  	if (ifp->if_flags & IFF_RUNNING) return;
  
***************
*** 358,364 ****
  	outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP);
  	outb(nec+ds1_curr, ns->ns_rxstart);
  	outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START);
! 	outb (nec+ds0_rcr, DSRC_AB);
  	outb(nec+ds0_dcr, ns->ns_mode);
  	outb (nec+ds0_imr, 0xff);
  
--- 387,396 ----
  	outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP);
  	outb(nec+ds1_curr, ns->ns_rxstart);
  	outb (nec+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START);
! 	if (ns->ns_if.if_flags & IFF_PROMISC)
! 		outb (nec+ds0_rcr, DSRC_AB|DSRC_PRO);
! 	else
! 		outb (nec+ds0_rcr, DSRC_AB);
  	outb(nec+ds0_dcr, ns->ns_mode);
  	outb (nec+ds0_imr, 0xff);
  
***************
*** 417,435 ****
  		
  	m = m0;
  	total = t;
  	for (m0 = m; m != 0; ) {
- 		
  		if (m->m_len&1 && t > m->m_len) {
! 			neput(ns, mtod(m, caddr_t), buffer, m->m_len - 1);
! 			t -= m->m_len - 1;
! 			buffer += m->m_len - 1;
! 			m->m_data += m->m_len - 1;
  			m->m_len = 1;
  			m = m_pullup(m, 2);
  		} else {
  			neput(ns, mtod(m, caddr_t), buffer, m->m_len);
- 			buffer += m->m_len;
  			t -= m->m_len;
  			MFREE(m, m0);
  			m = m0;
  		}
--- 449,473 ----
  		
  	m = m0;
  	total = t;
+ 
+ #if NBPFILTER > 0
+ 	if (ns->ns_bpf)
+ 		bpf_mtap(ns->ns_bpf, m);
+ #endif
+ 
  	for (m0 = m; m != 0; ) {
  		if (m->m_len&1 && t > m->m_len) {
! 			m->m_len -= 1;
! 			neput(ns, mtod(m, caddr_t), buffer, m->m_len);
! 			t -= m->m_len;
! 			buffer += m->m_len;
! 			m->m_data += m->m_len;
  			m->m_len = 1;
  			m = m_pullup(m, 2);
  		} else {
  			neput(ns, mtod(m, caddr_t), buffer, m->m_len);
  			t -= m->m_len;
+ 			buffer += m->m_len;
  			MFREE(m, m0);
  			m = m0;
  		}
***************
*** 648,653 ****
--- 686,703 ----
  
  	if (len == 0) return;
  
+ #if NBPFILTER > 0
+ 	if (ns->ns_bpf)
+ 		bpf_tap(ns->ns_bpf, buf, len + sizeof(struct ether_header));
+ #endif
+ 
+ 	if ((ns->ns_if.if_flags & IFF_PROMISC)
+ 	    && bcmp(eh->ether_dhost, ns->ns_addr,
+ 		    sizeof(eh->ether_dhost)) != 0
+ 	    && bcmp(eh->ether_dhost, etherbroadcastaddr,
+ 		    sizeof(eh->ether_dhost)) != 0)
+ 		return;
+ 
  	/*
  	 * Pull packet off interface.  Off is nonzero if packet
  	 * has trailing header; neget will then force this header
***************
*** 797,802 ****
--- 847,857 ----
  		break;
  
  	case SIOCSIFFLAGS:
+ #ifdef NEDEBUG
+ 		printf ("ne: setting flags, up: %s, running: %s\n",
+ 			ifp->if_flags & IFF_UP ? "yes" : "no",
+ 			ifp->if_flags & IFF_RUNNING ? "yes" : "no");
+ #endif
  		if ((ifp->if_flags & IFF_UP) == 0 &&
  		    ifp->if_flags & IFF_RUNNING) {
  			ifp->if_flags &= ~IFF_RUNNING;
-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----

-- 
 \  /   Charles Hannum, mycroft@ai.mit.edu
 /\ \   PGP public key available on request.  MIME, AMS, NextMail accepted.
Scheme  White heterosexual atheist male (WHAM) pride!
Newsgroups: comp.unix.bsd