diff -Nrau net/bridge/if_bridge.c net.new/bridge/if_bridge.c --- net/bridge/if_bridge.c 2006-10-01 00:10:19.000000000 +0300 +++ net.new/bridge/if_bridge.c 2006-12-15 17:42:54.000000000 +0200 @@ -1723,6 +1723,21 @@ if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0) goto out; + /* + * Implement support for bridge monitoring. If this flag has been + * set on this interface, discard the packet once we push it through + * the bpf(4) machinery, but before we do, increment the byte and + * packet counters associated with this interface. + */ + if ((bifp->if_flags & IFF_MONITOR) != 0) { + m->m_pkthdr.rcvif = bifp; + BPF_MTAP(bifp, m); + bifp->if_ipackets++; + bifp->if_ibytes += m->m_pkthdr.len; + m_freem(m); + goto out; + } + bif = bridge_lookup_member_if(sc, ifp); if (bif == NULL) goto out; diff -Nrau net/if.h net.new/if.h --- net/if.h 2006-05-20 05:42:08.000000000 +0300 +++ net.new/if.h 2006-12-15 17:42:55.000000000 +0200 @@ -148,6 +148,7 @@ #define IFF_MULTICAST 0x8000 /* supports multicast */ #define IFF_POLLING 0x10000 /* Interface is in polling mode. */ #define IFF_PPROMISC 0x20000 /* user-requested promisc mode */ +#define IFF_MONITOR 0x40000 /* user-requested monitor mode */ /* flags set internally only: */ #define IFF_CANTCHANGE \ diff -Nrau net/if_ethersubr.c net.new/if_ethersubr.c --- net/if_ethersubr.c 2006-07-02 03:49:22.000000000 +0300 +++ net.new/if_ethersubr.c 2006-12-15 17:42:55.000000000 +0200 @@ -162,6 +162,8 @@ ASSERT_SERIALIZED(ifp->if_serializer); + if (ifp->if_flags & IFF_MONITOR) + gotoerr(ENETDOWN); if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) gotoerr(ENETDOWN); @@ -570,6 +572,14 @@ BPF_MTAP(ifp, m); ifp->if_ibytes += m->m_pkthdr.len; + + if (ifp->if_flags & IFF_MONITOR) { + /* + * Interface marked for monitoring; discard packet. + */ + m_freem(m); + return; + } /* * Tap the packet off here for a bridge. bridge_input()