Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 09 Sep 2005 10:20:50 +0400
From:      "Vladimir Yu. Stepanov" <vys@renet.ru>
To:        freebsd-net@freebsd.org
Subject:   BPF patch for addition of good feature linux packet (7) (see attachment)
Message-ID:  <432129C2.8090405@renet.ru>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050009020007020700010608
Content-Type: text/plain; charset=KOI8-R; format=flowed
Content-Transfer-Encoding: 7bit


     Hello!

I made a modernization of bpf realization. It have a mind when we are 
trying to use bpf to account network statistic. When packets is catching 
by filter thereis imposible to determine the direction of packets flows. 
Due to this problem statistic accounts two times when packets is routes 
by the same interface, because this packets counts  as incoming  and 
outgoing traffic. The prototype of this patch is packet(7) on linux.

This patch is fully compatible with all program uses the bpf. It adds
the tags means traffic direction to the struct bpf_hdr.


struct bpf_hdr {
         struct timeval  bh_tstamp;      /* time stamp */
         bpf_u_int32     bh_caplen;      /* length of captured portion */
         bpf_u_int32     bh_datalen;     /* original length of packet */
         u_short         bh_hdrlen;      /* length of bpf header (this 
struct
                                            plus alignment padding) */
         u_short         bh_pkttype;     /* packet type */
};
/*
  * Packet types.
  * For help to get some extra information.
  * It is taken from the description packet(7) in Linux system.
  */
#define BPFPKTTYPE_HOST         0       /* To us */
#define BPFPKTTYPE_BROADCAST    1       /* To all */
#define BPFPKTTYPE_MULTICAST    2       /* To group */
#define BPFPKTTYPE_OTHERHOST    3       /* To someone else */
#define BPFPKTTYPE_OUTGOING     4       /* Outgoing of any type */
#define BPFPKTTYPE_LOOPBACK     5       /* MC/BRD frame looped back */
#define BPFPKTTYPE_FASTROUTE    6       /* Fastrouted frame (if cannot 
detect MC/BRD type) */


--------------050009020007020700010608
Content-Type: text/plain;
 name="freebsd-5.1-bpf-2.0-r4.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="freebsd-5.1-bpf-2.0-r4.patch"

diff -ruN sys.orig/net/bpf.c sys/net/bpf.c
--- sys.orig/net/bpf.c	Fri Dec 12 17:43:55 2003
+++ sys/net/bpf.c	Fri Apr 15 20:40:31 2005
@@ -106,7 +106,7 @@
 static __inline void
 		bpf_wakeup(struct bpf_d *);
 static void	catchpacket(struct bpf_d *, u_char *, u_int,
-		    u_int, void (*)(const void *, void *, size_t));
+		    u_int, u_int, void (*)(const void *, void *, size_t));
 static void	reset_d(struct bpf_d *);
 static int	 bpf_setf(struct bpf_d *, struct bpf_program *);
 static int	bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
@@ -1094,7 +1094,7 @@
 #ifdef MAC
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
-				catchpacket(d, pkt, pktlen, slen, bcopy);
+				catchpacket(d, pkt, pktlen, slen, BPFPKTTYPE_FASTROUTE, bcopy);
 		}
 		BPFD_UNLOCK(d);
 	}
@@ -1137,15 +1137,32 @@
 	struct mbuf *m;
 {
 	struct bpf_d *d;
-	u_int pktlen, slen;
+	u_int pktlen, slen, pkttype;
 
 	pktlen = m_length(m, NULL);
-	if (pktlen == m->m_len) {
-		bpf_tap(bp, mtod(m, u_char *), pktlen);
-		return;
-	}
 
 	BPFIF_LOCK(bp);
+ 	if (m->m_pkthdr.rcvif == NULL)
+ 		pkttype = BPFPKTTYPE_OUTGOING;
+ 	else
+ 	if (m->m_pkthdr.rcvif != bp->bif_ifp)
+ 		pkttype = BPFPKTTYPE_OUTGOING;
+ 	else
+ 	if ((m->m_flags&M_BPF_TAGGED) == M_BPF_TAGGED)
+ 		pkttype = BPFPKTTYPE_OUTGOING;
+ 	else {
+ 		if ((m->m_flags&M_BCAST) != 0)
+ 			pkttype = BPFPKTTYPE_BROADCAST;
+ 		else
+ 		if ((m->m_flags&M_MCAST) != 0)
+ 			pkttype = BPFPKTTYPE_MULTICAST;
+ 		else
+ 			/* How to detect if packet may received
+ 			 * only in promiscuous mode ? */
+ 			pkttype = BPFPKTTYPE_HOST;
+ 	}
+ 	if (m->m_pkthdr.rcvif != NULL && (m->m_flags&M_RDONLY) != M_RDONLY)
+ 		m->m_flags |= M_BPF_TAGGED;
 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
 		if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
 			continue;
@@ -1157,7 +1174,7 @@
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
 				catchpacket(d, (u_char *)m, pktlen, slen,
-				    bpf_mcopy);
+				    pkttype, bpf_mcopy);
 		BPFD_UNLOCK(d);
 	}
 	BPFIF_UNLOCK(bp);
@@ -1172,10 +1189,10 @@
  * pkt is really an mbuf.
  */
 static void
-catchpacket(d, pkt, pktlen, snaplen, cpfn)
+catchpacket(d, pkt, pktlen, snaplen, pkttype, cpfn)
 	struct bpf_d *d;
 	u_char *pkt;
-	u_int pktlen, snaplen;
+	u_int pktlen, snaplen, pkttype;
 	void (*cpfn)(const void *, void *, size_t);
 {
 	struct bpf_hdr *hp;
@@ -1228,6 +1245,7 @@
 	microtime(&hp->bh_tstamp);
 	hp->bh_datalen = pktlen;
 	hp->bh_hdrlen = hdrlen;
+	hp->bh_pkttype = pkttype;
 	/*
 	 * Copy the packet data into the store buffer and update its length.
 	 */
@@ -1326,11 +1344,11 @@
 
 	/*
 	 * Compute the length of the bpf header.  This is not necessarily
-	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
-	 * that the network layer header begins on a longword boundary (for
-	 * performance reasons and to alleviate alignment restrictions).
+	 * equal to sizeof(struct bpf_hdr) because we want to insert spacing
+	 * such that the network layer header begins on a longword boundary
+	 * (for performance reasons and to alleviate alignment restrictions).
 	 */
-	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
+	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + sizeof(struct bpf_hdr)) - hdrlen;
 
 	if (bootverbose)
 		if_printf(ifp, "bpf attached\n");
diff -ruN sys.orig/net/bpf.h sys/net/bpf.h
--- sys.orig/net/bpf.h	Fri Dec 12 17:43:55 2003
+++ sys/net/bpf.h	Fri Apr 15 20:40:31 2005
@@ -94,7 +94,7 @@
 };
 /* Current version number of filter architecture. */
 #define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
+#define BPF_MINOR_VERSION 2
 
 #define	BIOCGBLEN	_IOR('B',102, u_int)
 #define	BIOCSBLEN	_IOWR('B',102, u_int)
@@ -127,16 +127,21 @@
 	bpf_u_int32	bh_datalen;	/* original length of packet */
 	u_short		bh_hdrlen;	/* length of bpf header (this struct
 					   plus alignment padding) */
+	u_short		bh_pkttype;	/* packet type */
 };
+
 /*
- * Because the structure above is not a multiple of 4 bytes, some compilers
- * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
- * Only the kernel needs to know about it; applications use bh_hdrlen.
+ * Packet types.
+ * For help to get some extra information.
+ * It is taken from the description packet(7) in Linux system.
  */
-#ifdef _KERNEL
-#define	SIZEOF_BPF_HDR	(sizeof(struct bpf_hdr) <= 20 ? 18 : \
-    sizeof(struct bpf_hdr))
-#endif
+#define BPFPKTTYPE_HOST		0	/* To us */
+#define BPFPKTTYPE_BROADCAST	1	/* To all */
+#define BPFPKTTYPE_MULTICAST	2	/* To group */
+#define BPFPKTTYPE_OTHERHOST	3	/* To someone else */
+#define BPFPKTTYPE_OUTGOING	4	/* Outgoing of any type */
+#define BPFPKTTYPE_LOOPBACK	5	/* MC/BRD frame looped back */
+#define BPFPKTTYPE_FASTROUTE	6	/* Fastrouted frame (if cannot detect MC/BRD type) */
 
 /*
  * Data-link level type codes.
diff -ruN sys.orig/sys/mbuf.h sys/sys/mbuf.h
--- sys.orig/sys/mbuf.h	Fri Dec 12 17:43:59 2003
+++ sys/sys/mbuf.h	Fri Apr 15 20:40:31 2005
@@ -163,6 +163,7 @@
 #define	M_FRAG		0x0800	/* packet is a fragment of a larger packet */
 #define	M_FIRSTFRAG	0x1000	/* packet is first fragment */
 #define	M_LASTFRAG	0x2000	/* packet is last fragment */
+#define	M_BPF_TAGGED	0x400000
 
 /*
  * External buffer types: identify ext_buf type.

--------------050009020007020700010608
Content-Type: text/plain;
 name="freebsd-5.2.1-bpf-2.0-r4.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="freebsd-5.2.1-bpf-2.0-r4.patch"

diff -ruN sys.orig/net/bpf.c sys/net/bpf.c
--- sys.orig/net/bpf.c	Thu Dec  2 19:07:36 2004
+++ sys/net/bpf.c	Fri Apr 15 16:39:39 2005
@@ -110,7 +110,7 @@
 static __inline void
 		bpf_wakeup(struct bpf_d *);
 static void	catchpacket(struct bpf_d *, u_char *, u_int,
-		    u_int, void (*)(const void *, void *, size_t));
+		    u_int, u_int, void (*)(const void *, void *, size_t));
 static void	reset_d(struct bpf_d *);
 static int	 bpf_setf(struct bpf_d *, struct bpf_program *);
 static int	bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
@@ -1157,7 +1157,7 @@
 #ifdef MAC
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
-				catchpacket(d, pkt, pktlen, slen, bcopy);
+				catchpacket(d, pkt, pktlen, slen, BPFPKTTYPE_FASTROUTE, bcopy);
 		}
 		BPFD_UNLOCK(d);
 	}
@@ -1200,15 +1200,32 @@
 	struct mbuf *m;
 {
 	struct bpf_d *d;
-	u_int pktlen, slen;
+	u_int pktlen, slen, pkttype;
 
 	pktlen = m_length(m, NULL);
-	if (pktlen == m->m_len) {
-		bpf_tap(bp, mtod(m, u_char *), pktlen);
-		return;
-	}
 
 	BPFIF_LOCK(bp);
+ 	if (m->m_pkthdr.rcvif == NULL)
+ 		pkttype = BPFPKTTYPE_OUTGOING;
+ 	else
+ 	if (m->m_pkthdr.rcvif != bp->bif_ifp)
+ 		pkttype = BPFPKTTYPE_OUTGOING;
+ 	else
+ 	if ((m->m_flags&M_BPF_TAGGED) == M_BPF_TAGGED)
+ 		pkttype = BPFPKTTYPE_OUTGOING;
+ 	else {
+ 		if ((m->m_flags&M_BCAST) != 0)
+ 			pkttype = BPFPKTTYPE_BROADCAST;
+ 		else
+ 		if ((m->m_flags&M_MCAST) != 0)
+ 			pkttype = BPFPKTTYPE_MULTICAST;
+ 		else
+ 			/* How to detect if packet may received
+ 			 * only in promiscuous mode ? */
+ 			pkttype = BPFPKTTYPE_HOST;
+ 	}
+ 	if (m->m_pkthdr.rcvif != NULL && (m->m_flags&M_RDONLY) != M_RDONLY)
+ 		m->m_flags |= M_BPF_TAGGED;
 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
 		if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
 			continue;
@@ -1220,7 +1237,7 @@
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
 				catchpacket(d, (u_char *)m, pktlen, slen,
-				    bpf_mcopy);
+				    pkttype, bpf_mcopy);
 		BPFD_UNLOCK(d);
 	}
 	BPFIF_UNLOCK(bp);
@@ -1235,10 +1252,10 @@
  * pkt is really an mbuf.
  */
 static void
-catchpacket(d, pkt, pktlen, snaplen, cpfn)
+catchpacket(d, pkt, pktlen, snaplen, pkttype, cpfn)
 	struct bpf_d *d;
 	u_char *pkt;
-	u_int pktlen, snaplen;
+	u_int pktlen, snaplen, pkttype;
 	void (*cpfn)(const void *, void *, size_t);
 {
 	struct bpf_hdr *hp;
@@ -1291,6 +1308,7 @@
 	microtime(&hp->bh_tstamp);
 	hp->bh_datalen = pktlen;
 	hp->bh_hdrlen = hdrlen;
+	hp->bh_pkttype = pkttype;
 	/*
 	 * Copy the packet data into the store buffer and update its length.
 	 */
@@ -1389,11 +1407,11 @@
 
 	/*
 	 * Compute the length of the bpf header.  This is not necessarily
-	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
-	 * that the network layer header begins on a longword boundary (for
-	 * performance reasons and to alleviate alignment restrictions).
+	 * equal to sizeof(struct bpf_hdr) because we want to insert spacing
+	 * such that the network layer header begins on a longword boundary
+	 * (for performance reasons and to alleviate alignment restrictions).
 	 */
-	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
+	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + sizeof(struct bpf_hdr)) - hdrlen;
 
 	if (bootverbose)
 		if_printf(ifp, "bpf attached\n");
diff -ruN sys.orig/net/bpf.h sys/net/bpf.h
--- sys.orig/net/bpf.h	Thu Dec  2 19:07:35 2004
+++ sys/net/bpf.h	Fri Apr 15 16:35:24 2005
@@ -94,7 +94,7 @@
 };
 /* Current version number of filter architecture. */
 #define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
+#define BPF_MINOR_VERSION 2
 
 #define	BIOCGBLEN	_IOR('B',102, u_int)
 #define	BIOCSBLEN	_IOWR('B',102, u_int)
@@ -127,16 +127,21 @@
 	bpf_u_int32	bh_datalen;	/* original length of packet */
 	u_short		bh_hdrlen;	/* length of bpf header (this struct
 					   plus alignment padding) */
+	u_short		bh_pkttype;	/* packet type */
 };
+
 /*
- * Because the structure above is not a multiple of 4 bytes, some compilers
- * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
- * Only the kernel needs to know about it; applications use bh_hdrlen.
+ * Packet types.
+ * For help to get some extra information.
+ * It is taken from the description packet(7) in Linux system.
  */
-#ifdef _KERNEL
-#define	SIZEOF_BPF_HDR	(sizeof(struct bpf_hdr) <= 20 ? 18 : \
-    sizeof(struct bpf_hdr))
-#endif
+#define BPFPKTTYPE_HOST		0	/* To us */
+#define BPFPKTTYPE_BROADCAST	1	/* To all */
+#define BPFPKTTYPE_MULTICAST	2	/* To group */
+#define BPFPKTTYPE_OTHERHOST	3	/* To someone else */
+#define BPFPKTTYPE_OUTGOING	4	/* Outgoing of any type */
+#define BPFPKTTYPE_LOOPBACK	5	/* MC/BRD frame looped back */
+#define BPFPKTTYPE_FASTROUTE	6	/* Fastrouted frame (if cannot detect MC/BRD type) */
 
 /*
  * Data-link level type codes.
diff -ruN sys.orig/sys/mbuf.h sys/sys/mbuf.h
--- sys.orig/sys/mbuf.h	Thu Dec  2 19:07:43 2004
+++ sys/sys/mbuf.h	Fri Apr 15 16:40:55 2005
@@ -164,6 +164,7 @@
 #define	M_FRAG		0x0800	/* packet is a fragment of a larger packet */
 #define	M_FIRSTFRAG	0x1000	/* packet is first fragment */
 #define	M_LASTFRAG	0x2000	/* packet is last fragment */
+#define	M_BPF_TAGGED	0x400000
 
 /*
  * External buffer types: identify ext_buf type.

--------------050009020007020700010608
Content-Type: text/plain;
 name="freebsd-5.3-bpf-2.0-r4.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="freebsd-5.3-bpf-2.0-r4.patch"

diff -ruN sys.orig/net/bpf.c sys/net/bpf.c
--- sys.orig/net/bpf.c	Mon Oct 11 07:45:21 2004
+++ sys/net/bpf.c	Fri Apr 15 10:31:39 2005
@@ -106,7 +106,7 @@
 static __inline void
 		bpf_wakeup(struct bpf_d *);
 static void	catchpacket(struct bpf_d *, u_char *, u_int,
-		    u_int, void (*)(const void *, void *, size_t));
+		    u_int, u_int, void (*)(const void *, void *, size_t));
 static void	reset_d(struct bpf_d *);
 static int	 bpf_setf(struct bpf_d *, struct bpf_program *);
 static int	bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
@@ -1162,7 +1162,7 @@
 #ifdef MAC
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
-				catchpacket(d, pkt, pktlen, slen, bcopy);
+				catchpacket(d, pkt, pktlen, slen, BPFPKTTYPE_FASTROUTE, bcopy);
 		}
 		BPFD_UNLOCK(d);
 	}
@@ -1205,7 +1205,7 @@
 	struct mbuf *m;
 {
 	struct bpf_d *d;
-	u_int pktlen, slen;
+	u_int pktlen, slen, pkttype;
 
 	/*
 	 * Lockless read to avoid cost of locking the interface if there are
@@ -1215,12 +1215,29 @@
 		return;
 
 	pktlen = m_length(m, NULL);
-	if (pktlen == m->m_len) {
-		bpf_tap(bp, mtod(m, u_char *), pktlen);
-		return;
-	}
 
 	BPFIF_LOCK(bp);
+	if (m->m_pkthdr.rcvif == NULL)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if (m->m_pkthdr.rcvif != bp->bif_ifp)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if ((m->m_flags&M_BPF_TAGGED) == M_BPF_TAGGED)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else {
+		if ((m->m_flags&M_BCAST) != 0)
+			pkttype = BPFPKTTYPE_BROADCAST;
+		else
+		if ((m->m_flags&M_MCAST) != 0)
+			pkttype = BPFPKTTYPE_MULTICAST;
+		else
+			/* How to detect if packet may received
+			 * only in promiscuous mode ? */
+			pkttype = BPFPKTTYPE_HOST;
+	}
+	if (m->m_pkthdr.rcvif != NULL && (m->m_flags&M_RDONLY) != M_RDONLY)
+		m->m_flags |= M_BPF_TAGGED;
 	LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
 		if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
 			continue;
@@ -1232,7 +1249,7 @@
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
 				catchpacket(d, (u_char *)m, pktlen, slen,
-				    bpf_mcopy);
+				    pkttype, bpf_mcopy);
 		BPFD_UNLOCK(d);
 	}
 	BPFIF_UNLOCK(bp);
@@ -1251,7 +1268,7 @@
 {
 	struct mbuf mb;
 	struct bpf_d *d;
-	u_int pktlen, slen;
+	u_int pktlen, slen, pkttype;
 
 	/*
 	 * Lockless read to avoid cost of locking the interface if there are
@@ -1272,6 +1289,27 @@
 	pktlen += dlen;
 
 	BPFIF_LOCK(bp);
+	if (m->m_pkthdr.rcvif == NULL)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if (m->m_pkthdr.rcvif != bp->bif_ifp)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if ((m->m_flags&M_BPF_TAGGED) == M_BPF_TAGGED)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else {
+		if ((m->m_flags&M_BCAST) != 0)
+			pkttype = BPFPKTTYPE_BROADCAST;
+		else
+		if ((m->m_flags&M_MCAST) != 0)
+			pkttype = BPFPKTTYPE_MULTICAST;
+		else
+			/* How to detect if packet may received
+			 * only in promiscuous mode ? */
+			pkttype = BPFPKTTYPE_HOST;
+	}
+	if (m->m_pkthdr.rcvif != NULL && (m->m_flags&M_RDONLY) != M_RDONLY)
+		m->m_flags |= M_BPF_TAGGED;
 	LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
 		if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
 			continue;
@@ -1283,7 +1321,7 @@
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
 				catchpacket(d, (u_char *)&mb, pktlen, slen,
-				    bpf_mcopy);
+				    pkttype, bpf_mcopy);
 		BPFD_UNLOCK(d);
 	}
 	BPFIF_UNLOCK(bp);
@@ -1297,10 +1335,10 @@
  * pkt is really an mbuf.
  */
 static void
-catchpacket(d, pkt, pktlen, snaplen, cpfn)
+catchpacket(d, pkt, pktlen, snaplen, pkttype, cpfn)
 	struct bpf_d *d;
 	u_char *pkt;
-	u_int pktlen, snaplen;
+	u_int pktlen, snaplen, pkttype;
 	void (*cpfn)(const void *, void *, size_t);
 {
 	struct bpf_hdr *hp;
@@ -1354,6 +1392,7 @@
 	microtime(&hp->bh_tstamp);
 	hp->bh_datalen = pktlen;
 	hp->bh_hdrlen = hdrlen;
+	hp->bh_pkttype = pkttype;
 	/*
 	 * Copy the packet data into the store buffer and update its length.
 	 */
@@ -1451,11 +1490,11 @@
 
 	/*
 	 * Compute the length of the bpf header.  This is not necessarily
-	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
-	 * that the network layer header begins on a longword boundary (for
-	 * performance reasons and to alleviate alignment restrictions).
+	 * equal to sizeof(struct bpf_hdr) because we want to insert spacing
+	 * such that the network layer header begins on a longword boundary
+	 * (for performance reasons and to alleviate alignment restrictions).
 	 */
-	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
+	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + sizeof(struct bpf_hdr)) - hdrlen;
 
 	if (bootverbose)
 		if_printf(ifp, "bpf attached\n");
diff -ruN sys.orig/net/bpf.h sys/net/bpf.h
--- sys.orig/net/bpf.h	Sun May 30 21:03:48 2004
+++ sys/net/bpf.h	Fri Apr 15 09:28:16 2005
@@ -90,7 +90,7 @@
 };
 /* Current version number of filter architecture. */
 #define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
+#define BPF_MINOR_VERSION 2
 
 #define	BIOCGBLEN	_IOR('B',102, u_int)
 #define	BIOCSBLEN	_IOWR('B',102, u_int)
@@ -123,16 +123,21 @@
 	bpf_u_int32	bh_datalen;	/* original length of packet */
 	u_short		bh_hdrlen;	/* length of bpf header (this struct
 					   plus alignment padding) */
+	u_short		bh_pkttype;	/* packet type */
 };
+
 /*
- * Because the structure above is not a multiple of 4 bytes, some compilers
- * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
- * Only the kernel needs to know about it; applications use bh_hdrlen.
+ * Packet types.
+ * For help to get some extra information.
+ * It is taken from the description packet(7) in Linux system.
  */
-#ifdef _KERNEL
-#define	SIZEOF_BPF_HDR	(sizeof(struct bpf_hdr) <= 20 ? 18 : \
-    sizeof(struct bpf_hdr))
-#endif
+#define BPFPKTTYPE_HOST		0	/* To us */
+#define BPFPKTTYPE_BROADCAST	1	/* To all */
+#define BPFPKTTYPE_MULTICAST	2	/* To group */
+#define BPFPKTTYPE_OTHERHOST	3	/* To someone else */
+#define BPFPKTTYPE_OUTGOING	4	/* Outgoing of any type */
+#define BPFPKTTYPE_LOOPBACK	5	/* MC/BRD frame looped back */
+#define BPFPKTTYPE_FASTROUTE	6	/* Fastrouted frame (if cannot detect MC/BRD type) */
 
 /*
  * Data-link level type codes.
diff -ruN sys.orig/sys/mbuf.h sys/sys/mbuf.h
--- sys.orig/sys/mbuf.h	Sat Oct 16 01:45:13 2004
+++ sys/sys/mbuf.h	Fri Apr 15 09:42:31 2005
@@ -178,6 +178,7 @@
 #define	M_FRAG		0x0800	/* packet is a fragment of a larger packet */
 #define	M_FIRSTFRAG	0x1000	/* packet is first fragment */
 #define	M_LASTFRAG	0x2000	/* packet is last fragment */
+#define	M_BPF_TAGGED	0x400000
 
 /*
  * External buffer types: identify ext_buf type.

--------------050009020007020700010608
Content-Type: text/plain;
 name="freebsd-5.4-bpf-2.0-r4.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="freebsd-5.4-bpf-2.0-r4.patch"

diff -ruN sys.orig/net/bpf.c sys/net/bpf.c
--- sys.orig/net/bpf.c	Thu Jun 16 14:41:15 2005
+++ sys/net/bpf.c	Thu Jun 16 14:45:59 2005
@@ -109,7 +109,7 @@
 static __inline void
 		bpf_wakeup(struct bpf_d *);
 static void	catchpacket(struct bpf_d *, u_char *, u_int,
-		    u_int, void (*)(const void *, void *, size_t));
+		    u_int, u_int, void (*)(const void *, void *, size_t));
 static void	reset_d(struct bpf_d *);
 static int	 bpf_setf(struct bpf_d *, struct bpf_program *);
 static int	bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
@@ -1168,7 +1168,7 @@
 #ifdef MAC
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
-				catchpacket(d, pkt, pktlen, slen, bcopy);
+				catchpacket(d, pkt, pktlen, slen, BPFPKTTYPE_FASTROUTE, bcopy);
 		}
 		BPFD_UNLOCK(d);
 	}
@@ -1211,7 +1211,7 @@
 	struct mbuf *m;
 {
 	struct bpf_d *d;
-	u_int pktlen, slen;
+	u_int pktlen, slen, pkttype;
 
 	/*
 	 * Lockless read to avoid cost of locking the interface if there are
@@ -1221,12 +1221,29 @@
 		return;
 
 	pktlen = m_length(m, NULL);
-	if (pktlen == m->m_len) {
-		bpf_tap(bp, mtod(m, u_char *), pktlen);
-		return;
-	}
 
 	BPFIF_LOCK(bp);
+	if (m->m_pkthdr.rcvif == NULL)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if (m->m_pkthdr.rcvif != bp->bif_ifp)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if ((m->m_flags&M_BPF_TAGGED) == M_BPF_TAGGED)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else {
+		if ((m->m_flags&M_BCAST) != 0)
+			pkttype = BPFPKTTYPE_BROADCAST;
+		else
+		if ((m->m_flags&M_MCAST) != 0)
+			pkttype = BPFPKTTYPE_MULTICAST;
+		else
+			/* How to detect if packet may received
+			 * only in promiscuous mode ? */
+			pkttype = BPFPKTTYPE_HOST;
+	}
+	if (m->m_pkthdr.rcvif != NULL && (m->m_flags&M_RDONLY) != M_RDONLY)
+		m->m_flags |= M_BPF_TAGGED;
 	LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
 		if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
 			continue;
@@ -1238,7 +1255,7 @@
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
 				catchpacket(d, (u_char *)m, pktlen, slen,
-				    bpf_mcopy);
+				    pkttype, bpf_mcopy);
 		BPFD_UNLOCK(d);
 	}
 	BPFIF_UNLOCK(bp);
@@ -1257,7 +1274,7 @@
 {
 	struct mbuf mb;
 	struct bpf_d *d;
-	u_int pktlen, slen;
+	u_int pktlen, slen, pkttype;
 
 	/*
 	 * Lockless read to avoid cost of locking the interface if there are
@@ -1278,6 +1295,27 @@
 	pktlen += dlen;
 
 	BPFIF_LOCK(bp);
+	if (m->m_pkthdr.rcvif == NULL)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if (m->m_pkthdr.rcvif != bp->bif_ifp)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else
+	if ((m->m_flags&M_BPF_TAGGED) == M_BPF_TAGGED)
+		pkttype = BPFPKTTYPE_OUTGOING;
+	else {
+		if ((m->m_flags&M_BCAST) != 0)
+			pkttype = BPFPKTTYPE_BROADCAST;
+		else
+		if ((m->m_flags&M_MCAST) != 0)
+			pkttype = BPFPKTTYPE_MULTICAST;
+		else
+			/* How to detect if packet may received
+			 * only in promiscuous mode ? */
+			pkttype = BPFPKTTYPE_HOST;
+	}
+	if (m->m_pkthdr.rcvif != NULL && (m->m_flags&M_RDONLY) != M_RDONLY)
+		m->m_flags |= M_BPF_TAGGED;
 	LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
 		if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
 			continue;
@@ -1289,7 +1327,7 @@
 			if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
 #endif
 				catchpacket(d, (u_char *)&mb, pktlen, slen,
-				    bpf_mcopy);
+				    pkttype, bpf_mcopy);
 		BPFD_UNLOCK(d);
 	}
 	BPFIF_UNLOCK(bp);
@@ -1303,10 +1341,10 @@
  * pkt is really an mbuf.
  */
 static void
-catchpacket(d, pkt, pktlen, snaplen, cpfn)
+catchpacket(d, pkt, pktlen, snaplen, pkttype, cpfn)
 	struct bpf_d *d;
 	u_char *pkt;
-	u_int pktlen, snaplen;
+	u_int pktlen, snaplen, pkttype;
 	void (*cpfn)(const void *, void *, size_t);
 {
 	struct bpf_hdr *hp;
@@ -1361,6 +1399,7 @@
 	microtime(&hp->bh_tstamp);
 	hp->bh_datalen = pktlen;
 	hp->bh_hdrlen = hdrlen;
+	hp->bh_pkttype = pkttype;
 	/*
 	 * Copy the packet data into the store buffer and update its length.
 	 */
@@ -1461,11 +1500,11 @@
 
 	/*
 	 * Compute the length of the bpf header.  This is not necessarily
-	 * equal to SIZEOF_BPF_HDR because we want to insert spacing such
-	 * that the network layer header begins on a longword boundary (for
-	 * performance reasons and to alleviate alignment restrictions).
+	 * equal to sizeof(struct bpf_hdr) because we want to insert spacing
+	 * such that the network layer header begins on a longword boundary
+	 * (for performance reasons and to alleviate alignment restrictions).
 	 */
-	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
+	bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + sizeof(struct bpf_hdr)) - hdrlen;
 
 	if (bootverbose)
 		if_printf(ifp, "bpf attached\n");
diff -ruN sys.orig/net/bpf.h sys/net/bpf.h
--- sys.orig/net/bpf.h	Thu Jun 16 14:41:15 2005
+++ sys/net/bpf.h	Thu Jun 16 14:45:59 2005
@@ -90,7 +90,7 @@
 };
 /* Current version number of filter architecture. */
 #define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
+#define BPF_MINOR_VERSION 2
 
 #define	BIOCGBLEN	_IOR('B',102, u_int)
 #define	BIOCSBLEN	_IOWR('B',102, u_int)
@@ -123,16 +123,21 @@
 	bpf_u_int32	bh_datalen;	/* original length of packet */
 	u_short		bh_hdrlen;	/* length of bpf header (this struct
 					   plus alignment padding) */
+	u_short		bh_pkttype;	/* packet type */
 };
+
 /*
- * Because the structure above is not a multiple of 4 bytes, some compilers
- * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
- * Only the kernel needs to know about it; applications use bh_hdrlen.
+ * Packet types.
+ * For help to get some extra information.
+ * It is taken from the description packet(7) in Linux system.
  */
-#ifdef _KERNEL
-#define	SIZEOF_BPF_HDR	(sizeof(struct bpf_hdr) <= 20 ? 18 : \
-    sizeof(struct bpf_hdr))
-#endif
+#define BPFPKTTYPE_HOST		0	/* To us */
+#define BPFPKTTYPE_BROADCAST	1	/* To all */
+#define BPFPKTTYPE_MULTICAST	2	/* To group */
+#define BPFPKTTYPE_OTHERHOST	3	/* To someone else */
+#define BPFPKTTYPE_OUTGOING	4	/* Outgoing of any type */
+#define BPFPKTTYPE_LOOPBACK	5	/* MC/BRD frame looped back */
+#define BPFPKTTYPE_FASTROUTE	6	/* Fastrouted frame (if cannot detect MC/BRD type) */
 
 /*
  * Data-link level type codes.
diff -ruN sys.orig/sys/mbuf.h sys/sys/mbuf.h
--- sys.orig/sys/mbuf.h	Thu Jun 16 14:41:19 2005
+++ sys/sys/mbuf.h	Thu Jun 16 14:45:59 2005
@@ -178,6 +178,7 @@
 #define	M_FRAG		0x0800	/* packet is a fragment of a larger packet */
 #define	M_FIRSTFRAG	0x1000	/* packet is first fragment */
 #define	M_LASTFRAG	0x2000	/* packet is last fragment */
+#define	M_BPF_TAGGED	0x400000
 
 /*
  * External buffer types: identify ext_buf type.

--------------050009020007020700010608--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?432129C2.8090405>