Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Aug 1995 20:31:18 PDT
From:      Bill Fenner <fenner@parc.xerox.com>
To:        freebsd-current@freebsd.org
Subject:   Re: Getting tcpdump to work with the BPF
Message-ID:  <95Aug9.203124pdt.177475@crevenia.parc.xerox.com>
References:  <405vs1$ito@galaxy.ee.rochester.edu> <406pje$3tu@sol.ctr.columbia.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
In article <406pje$3tu@sol.ctr.columbia.edu>,
Bill Paul <wpaul@ctr.columbia.edu> wrote:
>You're not missing anything: it's the Intel EtherExpress 'ix' driver
>that's missing something. It doesn't yet include BPF support.

Although I know nothing about the EtherExpress in particular, I know what
BPF needs; these patches *should* do the trick.

  Bill

--- if_ix.c.orig	Thu Aug 10 03:06:30 1995
+++ if_ix.c	Thu Aug 10 03:26:52 1995
@@ -67,7 +67,6 @@
 extern char all_es_snpa[], all_is_snpa[], all_l1is_snpa[], all_l2is_snpa[];
 #endif /* ISO */
 
-/*ZZZ no work done on this, this is just here to remind me*/
 #include "bpfilter.h"
 #if NBPFILTER > 0
 #include <net/bpf.h>
@@ -645,6 +644,9 @@
 		bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDRESS_LENGTH);
 	}
 	printf("ix%d: address %s\n", unit, ether_sprintf(sc->arpcom.ac_enaddr));
+#if NBPFILTER > 0
+	bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+#endif
 	return(0);
 }
 
@@ -1253,10 +1255,6 @@
 	DEBUGDO(for (i = 0; i < 16; i ++) printf ("%02x", rb[i] & 0xFF);)
 	DEBUGDO(printf(":");)
 	DEBUGEND
-	/* trickery here, eh points right at memory on
-	 * the board.  eh is only used by ether_input,
-	 * it is not passed to the upper layer */
-	eh = (struct ether_header *)rb;
 
 	/* here we go, lets build an mbuf chain up to hold all this */
 	MGETHDR(m, M_DONTWAIT, MT_DATA);
@@ -1265,11 +1263,10 @@
 		return;
 	}
 	m0 = m;
+	eh = mtod(m, struct ether_header *);
 	length = rbd->act_count & RBD_STAT_SIZE;
-	bytesleft = length - sizeof(struct ether_header);
-	rb += sizeof(struct ether_header);
 	m->m_pkthdr.rcvif = ifp;
-	m->m_pkthdr.len = bytesleft;
+	m->m_pkthdr.len = length;
 	m->m_len = MHLEN;
 	while (bytesleft > 0) {
 		if (bytesleft > MINCLSIZE) {
@@ -1298,6 +1295,35 @@
 		}
 	}
 
+#if NBPFILTER > 0
+	/*
+	 * Check if there's a BPF listener on this interface. If so, hand off
+	 * the raw packet to bpf.
+	 */
+	if (sc->bpf) {
+		bpf_mtap(sc->bpf, m);
+
+		/*
+		 * If we are in promiscuous mode, we have to check if
+		 * this packet is really ours.
+		 */
+		if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
+		    bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
+		      sizeof(eh->ether_dhost)) != 0 &&
+		      !(eh->ether_dhost.ether_addr_octet[0] & 1)) {
+			m_freem(m);
+			return;
+		}
+	}
+#endif
+
+	/*
+	 * Remove link layer address.
+	 */
+	m->m_pkthdr.len -= sizeof(struct ether_header);
+	m->m_len -= sizeof(struct ether_header);
+	m->m_data += sizeof(struct ether_header);
+
 	ether_input(ifp, eh, m0);
 	ifp->if_ipackets++;
 	return;
@@ -1419,6 +1445,14 @@
 			tb += m_temp->m_len;
 			length += m_temp->m_len;
 		}
+#if NBPFILTER > 0
+		/* This really wants to be done after the packet has been
+		 * put on the wire, but this appears to be the easiest place
+		 * to insert it.
+		 */
+		if (sc->bpf)
+			bpf_mtap(sc->bpf, m);
+#endif
 		m_freem(m);
 		if (length < ETHER_MIN_LENGTH) length = ETHER_MIN_LENGTH;
 #ifdef DIAGNOSTIC



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?95Aug9.203124pdt.177475>