mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Move code to handle BPF and bridging for incoming Ethernet packets out
of the individual drivers and into the common routine ether_input(). Also, remove the (incomplete) hack for matching ethernet headers in the ip_fw code. The good news: net result of 1016 lines removed, and this should make bridging now work with *all* Ethernet drivers. The bad news: it's nearly impossible to test every driver, especially for bridging, and I was unable to get much testing help on the mailing lists. Reviewed by: freebsd-net
This commit is contained in:
parent
e3227bc7a6
commit
2e2de7f23f
53 changed files with 356 additions and 1698 deletions
|
|
@ -557,28 +557,6 @@ am7990_read(sc, boff, len)
|
|||
/* We assume that the header fit entirely in one mbuf. */
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface.
|
||||
* If so, hand off the raw packet to BPF.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
#ifndef LANCE_REVC_BUG
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode if
|
||||
* there are no BPF listeners. And if we are in promiscuous
|
||||
* mode, we have to check if this packet is really ours.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_PROMISC) != 0 &&
|
||||
(eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
|
||||
ETHER_CMP(eh->ether_dhost, sc->sc_enaddr)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LANCE_REVC_BUG
|
||||
/*
|
||||
* The old LANCE (Rev. C) chips have a bug which causes
|
||||
|
|
|
|||
|
|
@ -455,25 +455,12 @@ static void an_rxeof(sc)
|
|||
|
||||
ifp->if_ipackets++;
|
||||
|
||||
/* Handle BPF listeners. */
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive packet. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
#ifdef ANCACHE
|
||||
an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength);
|
||||
#endif
|
||||
ether_input(ifp, eh, m);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void an_txeof(sc, status)
|
||||
|
|
|
|||
|
|
@ -1311,7 +1311,9 @@ awi_input(sc, m, rxts, rssi)
|
|||
break;
|
||||
}
|
||||
ifp->if_ipackets++;
|
||||
#ifndef __FreeBSD__
|
||||
AWI_BPF_MTAP(sc, m, AWI_BPF_NORM);
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
m->m_flags |= M_HASFCS;
|
||||
(*ifp->if_input)(ifp, m);
|
||||
|
|
|
|||
|
|
@ -62,10 +62,6 @@
|
|||
|
||||
#include <isa/isavar.h>
|
||||
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <dev/cs/if_csreg.h>
|
||||
|
|
@ -952,9 +948,6 @@ cs_get_packet(struct cs_softc *sc)
|
|||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
#ifdef CS_DEBUG
|
||||
for (i=0;i<length;i++)
|
||||
printf(" %02x",(unsigned char)*((char *)(m->m_data+i)));
|
||||
|
|
|
|||
|
|
@ -122,11 +122,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -2133,47 +2128,12 @@ static void dc_rxeof(sc)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/* Handle BPF listeners. Let the BPF user see the packet */
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) && (bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
#endif
|
||||
|
||||
/* Don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
}
|
||||
|
||||
sc->dc_cdata.dc_rx_prod = i;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -89,11 +89,6 @@
|
|||
#include <pci/pcireg.h>
|
||||
#include <pci/dc21040reg.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Intel CPUs should use I/O mapped access.
|
||||
*/
|
||||
|
|
@ -3475,34 +3470,15 @@ tulip_rx_intr(
|
|||
#endif /* TULIP_BUS_DMA */
|
||||
|
||||
eh = *mtod(ms, struct ether_header *);
|
||||
#ifndef __FreeBSD__
|
||||
if (sc->tulip_if.if_bpf != NULL) {
|
||||
if (me == ms)
|
||||
bpf_tap(&sc->tulip_if, mtod(ms, caddr_t), total_len);
|
||||
else
|
||||
bpf_mtap(&sc->tulip_if, ms);
|
||||
}
|
||||
sc->tulip_flags |= TULIP_RXACT;
|
||||
|
||||
#ifdef BRIDGE /* see code in if_ed.c */
|
||||
ms->m_pkthdr.rcvif = ifp; /* XXX */
|
||||
ms->m_pkthdr.len = total_len; /* XXX */
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(ms);
|
||||
if (bdg_ifp == BDG_DROP)
|
||||
goto next ; /* and drop */
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&ms, bdg_ifp);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST &&
|
||||
bdg_ifp != BDG_MCAST)
|
||||
goto next ; /* and drop */
|
||||
/* all others accepted locally */
|
||||
} else
|
||||
#endif
|
||||
if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY))
|
||||
&& (eh.ether_dhost[0] & 1) == 0
|
||||
&& !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr))
|
||||
goto next;
|
||||
sc->tulip_flags |= TULIP_RXACT;
|
||||
accept = 1;
|
||||
} else {
|
||||
ifp->if_ierrors++;
|
||||
|
|
@ -3551,7 +3527,6 @@ tulip_rx_intr(
|
|||
#endif
|
||||
#endif /* TULIP_BUS_DMA */
|
||||
}
|
||||
next:
|
||||
#if defined(TULIP_DEBUG)
|
||||
cnt++;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ static void ed_watchdog __P((struct ifnet *));
|
|||
|
||||
static void ds_getmcaf __P((struct ed_softc *, u_long *));
|
||||
|
||||
static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int, int));
|
||||
static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int));
|
||||
|
||||
static __inline void ed_rint __P((struct ed_softc *));
|
||||
static __inline void ed_xmit __P((struct ed_softc *));
|
||||
|
|
@ -2206,7 +2206,7 @@ ed_rint(sc)
|
|||
* Go get packet.
|
||||
*/
|
||||
ed_get_packet(sc, packet_ptr + sizeof(struct ed_ring),
|
||||
len - sizeof(struct ed_ring), packet_hdr.rsr & ED_RSR_PHY);
|
||||
len - sizeof(struct ed_ring));
|
||||
ifp->if_ipackets++;
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -2612,14 +2612,13 @@ ed_ring_copy(sc, src, dst, amount)
|
|||
|
||||
/*
|
||||
* Retreive packet from shared memory and send to the next level up via
|
||||
* ether_input(). If there is a BPF listener, give a copy to BPF, too.
|
||||
* ether_input().
|
||||
*/
|
||||
static void
|
||||
ed_get_packet(sc, buf, len, multicast)
|
||||
ed_get_packet(sc, buf, len)
|
||||
struct ed_softc *sc;
|
||||
char *buf;
|
||||
u_short len;
|
||||
int multicast;
|
||||
{
|
||||
struct ether_header *eh;
|
||||
struct mbuf *m;
|
||||
|
|
@ -2657,63 +2656,25 @@ ed_get_packet(sc, buf, len, multicast)
|
|||
|
||||
#ifdef BRIDGE
|
||||
/*
|
||||
* Get link layer header, invoke brige_in, then
|
||||
* depending on the outcome of the test fetch the rest of the
|
||||
* packet and either pass up or call bdg_forward.
|
||||
* Don't read in the entire packet if we know we're going to drop it
|
||||
*/
|
||||
if (do_bridge) {
|
||||
struct ifnet *ifp ;
|
||||
int need_more = 1 ; /* in case not bpf */
|
||||
struct ifnet *bif;
|
||||
|
||||
if (sc->arpcom.ac_if.if_bpf) {
|
||||
need_more = 0 ;
|
||||
ed_ring_copy(sc, buf, (char *)eh, len);
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
} else
|
||||
ed_ring_copy(sc, buf, (char *)eh, 14);
|
||||
ifp = bridge_in(m);
|
||||
if (ifp == BDG_DROP) {
|
||||
ed_ring_copy(sc, buf, (char *)eh, ETHER_HDR_LEN);
|
||||
if ((bif = bridge_in(&sc->arpcom.ac_if, eh)) == BDG_DROP) {
|
||||
m_freem(m);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
/* else fetch rest of pkt and continue */
|
||||
if (need_more && len > 14)
|
||||
ed_ring_copy(sc, buf+14, (char *)(eh+1), len - 14);
|
||||
if (ifp != BDG_LOCAL )
|
||||
bdg_forward(&m, ifp); /* not local, need forwarding */
|
||||
if (ifp == BDG_LOCAL || ifp == BDG_BCAST || ifp == BDG_MCAST)
|
||||
goto getit ;
|
||||
/* not local and not multicast, just drop it */
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return ;
|
||||
}
|
||||
ed_ring_copy(sc, buf + ETHER_HDR_LEN,
|
||||
(char *)eh + ETHER_HDR_LEN, len - ETHER_HDR_LEN);
|
||||
} else
|
||||
#endif
|
||||
/*
|
||||
* Get packet, including link layer address, from interface.
|
||||
*/
|
||||
ed_ring_copy(sc, buf, (char *)eh, len);
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface. If so, hand off
|
||||
* the raw packet to bpf.
|
||||
*/
|
||||
if (sc->arpcom.ac_if.if_bpf)
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
/*
|
||||
* If we are in promiscuous mode, we have to check whether
|
||||
* this packet is really for us.
|
||||
*/
|
||||
if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
|
||||
bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost)) != 0 && multicast == 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
/*
|
||||
* Remove link layer address.
|
||||
*/
|
||||
|
|
@ -2721,7 +2682,6 @@ getit:
|
|||
m->m_data += sizeof(struct ether_header);
|
||||
|
||||
ether_input(&sc->arpcom.ac_if, eh, m);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -410,8 +410,7 @@ ep_if_init(xsc)
|
|||
|
||||
#ifdef EP_LOCAL_STATS
|
||||
sc->rx_no_first = sc->rx_no_mbuf =
|
||||
sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
|
||||
sc->tx_underrun = 0;
|
||||
sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
|
||||
#endif
|
||||
EP_FSET(sc, F_RX_FIRST);
|
||||
if (sc->top) {
|
||||
|
|
@ -593,8 +592,8 @@ rescan:
|
|||
printf("\tStat: %x\n", sc->stat);
|
||||
printf("\tIpackets=%d, Opackets=%d\n",
|
||||
ifp->if_ipackets, ifp->if_opackets);
|
||||
printf("\tNOF=%d, NOMB=%d, BPFD=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
|
||||
sc->rx_no_first, sc->rx_no_mbuf, sc->rx_bpf_disc, sc->rx_overrunf,
|
||||
printf("\tNOF=%d, NOMB=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
|
||||
sc->rx_no_first, sc->rx_no_mbuf, sc->rx_overrunf,
|
||||
sc->rx_overrunl, sc->tx_underrun);
|
||||
#else
|
||||
|
||||
|
|
@ -772,35 +771,6 @@ read_again:
|
|||
top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
|
||||
top->m_pkthdr.len = sc->cur_len;
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, top);
|
||||
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode if there are
|
||||
* no BPF listeners. And if we are in promiscuous mode, we have to
|
||||
* check if this packet is really ours.
|
||||
*/
|
||||
eh = mtod(top, struct ether_header *);
|
||||
if ((ifp->if_flags & IFF_PROMISC) &&
|
||||
(eh->ether_dhost[0] & 1) == 0 &&
|
||||
bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost)) != 0 &&
|
||||
bcmp(eh->ether_dhost, etherbroadcastaddr,
|
||||
sizeof(eh->ether_dhost)) != 0) {
|
||||
if (sc->top) {
|
||||
m_freem(sc->top);
|
||||
sc->top = 0;
|
||||
}
|
||||
EP_FSET(sc, F_RX_FIRST);
|
||||
#ifdef EP_LOCAL_STATS
|
||||
sc->rx_bpf_disc++;
|
||||
#endif
|
||||
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||
outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
eh = mtod(top, struct ether_header *);
|
||||
m_adj(top, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, top);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ struct ep_softc {
|
|||
short tx_underrun;
|
||||
short rx_no_first;
|
||||
short rx_no_mbuf;
|
||||
short rx_bpf_disc;
|
||||
short rx_overrunf;
|
||||
short rx_overrunl;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -761,23 +761,6 @@ ex_rx_intr(struct ex_softc *sc)
|
|||
} /* QQQ */
|
||||
}
|
||||
#endif
|
||||
if (ifp->if_bpf != NULL) {
|
||||
bpf_mtap(ifp, ipkt);
|
||||
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode
|
||||
* if there are no BPF listeners. And if we are in
|
||||
* promiscuous mode, we have to check if this packet is
|
||||
* really ours.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_PROMISC) &&
|
||||
(eh->ether_dhost[0] & 1) == 0 &&
|
||||
bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, sizeof(eh->ether_dhost)) != 0 &&
|
||||
bcmp(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)) != 0) {
|
||||
m_freem(ipkt);
|
||||
goto rx_another;
|
||||
}
|
||||
}
|
||||
m_adj(ipkt, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, ipkt);
|
||||
ifp->if_ipackets++;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
* cons of multiple frame transmission.
|
||||
* o To test IPX codes.
|
||||
* o To test FreeBSD3.0-current.
|
||||
* o To test BRIDGE codes.
|
||||
*/
|
||||
|
||||
#include "fe.h"
|
||||
|
|
@ -92,10 +91,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
|
@ -3819,7 +3814,7 @@ fe_ioctl ( struct ifnet * ifp, u_long command, caddr_t data )
|
|||
|
||||
/*
|
||||
* Retrieve packet from receive buffer and send to the next level up via
|
||||
* ether_input(). If there is a BPF listener, give a copy to BPF, too.
|
||||
* ether_input().
|
||||
* Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
|
||||
*/
|
||||
static int
|
||||
|
|
@ -3897,61 +3892,6 @@ fe_get_packet ( struct fe_softc * sc, u_short len )
|
|||
insw( sc->ioaddr[ FE_BMPR8 ], eh, ( len + 1 ) >> 1 );
|
||||
}
|
||||
|
||||
#define ETHER_ADDR_IS_MULTICAST(A) (*(char *)(A) & 1)
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface.
|
||||
* If it is, hand off the raw packet to bpf.
|
||||
*/
|
||||
if ( sc->sc_if.if_bpf ) {
|
||||
bpf_mtap( &sc->sc_if, m );
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *ifp;
|
||||
|
||||
ifp = bridge_in(m);
|
||||
if (ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
return 0;
|
||||
}
|
||||
if (ifp != BDG_LOCAL)
|
||||
bdg_forward(&m, ifp); /* not local, need forwarding */
|
||||
if (ifp == BDG_LOCAL || ifp == BDG_BCAST || ifp == BDG_MCAST)
|
||||
goto getit;
|
||||
/* not local and not multicast, just drop it */
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure this packet is (or may be) directed to us.
|
||||
* That is, the packet is either unicasted to our address,
|
||||
* or broad/multi-casted. If any other packets are
|
||||
* received, it is an indication of an error -- probably
|
||||
* 86960 is in a wrong operation mode.
|
||||
* Promiscuous mode is an exception. Under the mode, all
|
||||
* packets on the media must be received. (We must have
|
||||
* programmed the 86960 so.)
|
||||
*/
|
||||
|
||||
if ( ( sc->sc_if.if_flags & IFF_PROMISC )
|
||||
&& !ETHER_ADDR_IS_MULTICAST( eh->ether_dhost )
|
||||
&& bcmp( eh->ether_dhost, sc->sc_enaddr, ETHER_ADDR_LEN ) != 0 ) {
|
||||
/*
|
||||
* The packet was not for us. This is normal since
|
||||
* we are now in promiscuous mode. Just drop the packet.
|
||||
*/
|
||||
m_freem( m );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
/* Strip off the Ethernet header. */
|
||||
m->m_pkthdr.len -= sizeof ( struct ether_header );
|
||||
m->m_len -= sizeof ( struct ether_header );
|
||||
|
|
|
|||
|
|
@ -105,13 +105,6 @@
|
|||
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
|
||||
#endif /* __alpha__ */
|
||||
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/if_types.h>
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE! On the Alpha, we have an alignment constraint. The
|
||||
* card DMAs the packet immediately following the RFA. However,
|
||||
|
|
@ -1169,53 +1162,13 @@ rcvloop:
|
|||
goto rcvloop;
|
||||
}
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
total_len ;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
if (ifp->if_bpf)
|
||||
bpf_tap(FXP_BPFTAP_ARG(ifp),
|
||||
mtod(m, caddr_t),
|
||||
total_len);
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp == BDG_DROP)
|
||||
goto dropit ;
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (bdg_ifp != BDG_LOCAL &&
|
||||
bdg_ifp != BDG_BCAST &&
|
||||
bdg_ifp != BDG_MCAST)
|
||||
goto dropit ;
|
||||
goto getit ;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Only pass this packet up
|
||||
* if it is for us.
|
||||
*/
|
||||
if ((ifp->if_flags &
|
||||
IFF_PROMISC) &&
|
||||
(rfa->rfa_status &
|
||||
FXP_RFA_STATUS_IAMATCH) &&
|
||||
(eh->ether_dhost[0] & 1)
|
||||
== 0) {
|
||||
#ifdef BRIDGE
|
||||
dropit:
|
||||
#endif
|
||||
if (m)
|
||||
m_freem(m);
|
||||
goto rcvloop;
|
||||
}
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
m->m_data +=
|
||||
sizeof(struct ether_header);
|
||||
m->m_len -=
|
||||
sizeof(struct ether_header);
|
||||
m->m_pkthdr.len = m->m_len ;
|
||||
m->m_pkthdr.len = m->m_len;
|
||||
ether_input(ifp, eh, m);
|
||||
}
|
||||
goto rcvloop;
|
||||
|
|
|
|||
|
|
@ -158,8 +158,6 @@ static int ie_debug = IED_RNR;
|
|||
/* Forward declaration */
|
||||
struct ie_softc;
|
||||
|
||||
static struct mbuf *last_not_for_us;
|
||||
|
||||
static int ieprobe(struct isa_device * dvp);
|
||||
static int ieattach(struct isa_device * dvp);
|
||||
static ointhand2_t ieintr;
|
||||
|
|
@ -202,7 +200,7 @@ static int ietint(int unit, struct ie_softc * ie);
|
|||
static int iernr(int unit, struct ie_softc * ie);
|
||||
static void start_receiver(int unit);
|
||||
static __inline int ieget(int, struct ie_softc *, struct mbuf **,
|
||||
struct ether_header *, int *);
|
||||
struct ether_header *);
|
||||
static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie);
|
||||
static int mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *);
|
||||
static void ie_mc_reset(int unit);
|
||||
|
|
@ -1029,102 +1027,48 @@ ether_equal(u_char * one, u_char * two)
|
|||
}
|
||||
|
||||
/*
|
||||
* Check for a valid address. to_bpf is filled in with one of the following:
|
||||
* 0 -> BPF doesn't get this packet
|
||||
* 1 -> BPF does get this packet
|
||||
* 2 -> BPF does get this packet, but we don't
|
||||
* Return value is true if the packet is for us, and false otherwise.
|
||||
*
|
||||
* This routine is a mess, but it's also critical that it be as fast
|
||||
* as possible. It could be made cleaner if we can assume that the
|
||||
* only client which will fiddle with IFF_PROMISC is BPF. This is
|
||||
* probably a good assumption, but we do not make it here. (Yet.)
|
||||
* Determine quickly whether we should bother reading in this packet.
|
||||
* This depends on whether BPF and/or bridging is enabled, whether we
|
||||
* are receiving multicast address, and whether promiscuous mode is enabled.
|
||||
* We assume that if IFF_PROMISC is set, then *somebody* wants to see
|
||||
* all incoming packets.
|
||||
*/
|
||||
static __inline int
|
||||
check_eh(struct ie_softc * ie, struct ether_header * eh, int *to_bpf)
|
||||
check_eh(struct ie_softc *ie, struct ether_header *eh)
|
||||
{
|
||||
int i;
|
||||
/* Optimize the common case: normal operation. We've received
|
||||
either a unicast with our dest or a multicast packet. */
|
||||
if (ie->promisc == 0) {
|
||||
int i;
|
||||
|
||||
switch (ie->promisc) {
|
||||
case IFF_ALLMULTI:
|
||||
/*
|
||||
* Receiving all multicasts, but no unicasts except those
|
||||
* destined for us.
|
||||
*/
|
||||
/* BPF gets this packet if anybody cares */
|
||||
*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
|
||||
if (eh->ether_dhost[0] & 1) {
|
||||
return (1);
|
||||
}
|
||||
if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
|
||||
return (1);
|
||||
return (0);
|
||||
|
||||
case IFF_PROMISC:
|
||||
/*
|
||||
* Receiving all packets. These need to be passed on to
|
||||
* BPF.
|
||||
*/
|
||||
*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
|
||||
/* If for us, accept and hand up to BPF */
|
||||
if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
|
||||
/* If not multicast, it's definitely for us */
|
||||
if ((eh->ether_dhost[0] & 1) == 0)
|
||||
return (1);
|
||||
|
||||
if (*to_bpf)
|
||||
*to_bpf = 2; /* we don't need to see it */
|
||||
|
||||
/*
|
||||
* Not a multicast, so BPF wants to see it but we don't.
|
||||
*/
|
||||
if (!(eh->ether_dhost[0] & 1))
|
||||
/* Accept broadcasts (loose but fast check) */
|
||||
if (eh->ether_dhost[0] == 0xff)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* If it's one of our multicast groups, accept it and pass
|
||||
* it up.
|
||||
*/
|
||||
/* Compare against our multicast addresses */
|
||||
for (i = 0; i < ie->mcast_count; i++) {
|
||||
if (ether_equal(eh->ether_dhost,
|
||||
(u_char *)&ie->mcast_addrs[i])) {
|
||||
if (*to_bpf)
|
||||
*to_bpf = 1;
|
||||
(u_char *)&ie->mcast_addrs[i]))
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
|
||||
case IFF_ALLMULTI | IFF_PROMISC:
|
||||
/*
|
||||
* Acting as a multicast router, and BPF running at the same
|
||||
* time. Whew! (Hope this is a fast machine...)
|
||||
*/
|
||||
*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
|
||||
/* We want to see multicasts. */
|
||||
if (eh->ether_dhost[0] & 1)
|
||||
return (1);
|
||||
|
||||
/* We want to see our own packets */
|
||||
if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
|
||||
return (1);
|
||||
|
||||
/* Anything else goes to BPF but nothing else. */
|
||||
if (*to_bpf)
|
||||
*to_bpf = 2;
|
||||
return (1);
|
||||
|
||||
default:
|
||||
/*
|
||||
* Only accept unicast packets destined for us, or
|
||||
* multicasts for groups that we belong to. For now, we
|
||||
* assume that the '586 will only return packets that we
|
||||
* asked it for. This isn't strictly true (it uses hashing
|
||||
* for the multicast filter), but it will do in this case,
|
||||
* and we want to get out of here as quickly as possible.
|
||||
*/
|
||||
*to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
|
||||
/* Always accept packets when in promiscuous mode */
|
||||
if ((ie->promisc & IFF_PROMISC) != 0)
|
||||
return (1);
|
||||
|
||||
/* Always accept packets directed at us */
|
||||
if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
|
||||
return (1);
|
||||
|
||||
/* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
|
||||
actually in promiscuous mode, so discard unicast packets. */
|
||||
return((eh->ether_dhost[0] & 1) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1177,8 +1121,7 @@ ie_packet_len(int unit, struct ie_softc * ie)
|
|||
* operation considerably. (Provided that it works, of course.)
|
||||
*/
|
||||
static __inline int
|
||||
ieget(int unit, struct ie_softc *ie, struct mbuf **mp,
|
||||
struct ether_header *ehp, int *to_bpf)
|
||||
ieget(int unit, struct ie_softc *ie, struct mbuf **mp, struct ether_header *ehp)
|
||||
{
|
||||
struct mbuf *m, *top, **mymp;
|
||||
int i;
|
||||
|
|
@ -1205,7 +1148,7 @@ ieget(int unit, struct ie_softc *ie, struct mbuf **mp,
|
|||
* This is only a consideration when FILTER is defined; i.e., when
|
||||
* we are either running BPF or doing multicasting.
|
||||
*/
|
||||
if (!check_eh(ie, ehp, to_bpf)) {
|
||||
if (!check_eh(ie, ehp)) {
|
||||
ie_drop_packet_buffer(unit, ie);
|
||||
ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
|
||||
* error
|
||||
|
|
@ -1356,8 +1299,6 @@ ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
|
|||
struct mbuf *m = 0;
|
||||
struct ether_header eh;
|
||||
|
||||
int bpf_gets_it = 0;
|
||||
|
||||
bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
|
||||
sizeof(struct ie_recv_frame_desc));
|
||||
|
||||
|
|
@ -1372,7 +1313,7 @@ ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
|
|||
ie->rfhead = (ie->rfhead + 1) % ie->nframes;
|
||||
|
||||
if (rfd.ie_fd_status & IE_FD_OK) {
|
||||
if (ieget(unit, ie, &m, &eh, &bpf_gets_it)) {
|
||||
if (ieget(unit, ie, &m, &eh)) {
|
||||
ie->arpcom.ac_if.if_ierrors++; /* this counts as an
|
||||
* error */
|
||||
return;
|
||||
|
|
@ -1391,45 +1332,6 @@ ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
|
|||
if (!m)
|
||||
return;
|
||||
|
||||
if (last_not_for_us) {
|
||||
m_freem(last_not_for_us);
|
||||
last_not_for_us = 0;
|
||||
}
|
||||
/*
|
||||
* Check for a BPF filter; if so, hand it up. Note that we have to
|
||||
* stick an extra mbuf up front, because bpf_mtap expects to have
|
||||
* the ether header at the front. It doesn't matter that this
|
||||
* results in an ill-formatted mbuf chain, since BPF just looks at
|
||||
* the data. (It doesn't try to free the mbuf, tho' it will make a
|
||||
* copy for tcpdump.)
|
||||
*/
|
||||
if (bpf_gets_it) {
|
||||
struct mbuf m0;
|
||||
|
||||
m0.m_len = sizeof eh;
|
||||
m0.m_data = (caddr_t)&eh;
|
||||
m0.m_next = m;
|
||||
|
||||
/* Pass it up */
|
||||
bpf_mtap(&ie->arpcom.ac_if, &m0);
|
||||
}
|
||||
/*
|
||||
* A signal passed up from the filtering code indicating that the
|
||||
* packet is intended for BPF but not for the protocol machinery. We
|
||||
* can save a few cycles by not handing it off to them.
|
||||
*/
|
||||
if (bpf_gets_it == 2) {
|
||||
last_not_for_us = m;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* In here there used to be code to check destination addresses upon
|
||||
* receipt of a packet. We have deleted that code, and replaced it
|
||||
* with code to check the address much earlier in the cycle, before
|
||||
* copying the data in; this saves us valuable cycles when operating
|
||||
* as a multicast router or when using BPF.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Finally pass this packet up to higher layers.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1019,20 +1019,9 @@ static void sf_rxeof(sc)
|
|||
eh = mtod(m, struct ether_header *);
|
||||
ifp->if_ipackets++;
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
||||
}
|
||||
|
||||
csr_write_4(sc, SF_CQ_CONSIDX,
|
||||
|
|
|
|||
|
|
@ -1654,16 +1654,6 @@ static void sk_rxeof(sc_if)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc_if->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -1096,26 +1096,6 @@ read_another:
|
|||
}
|
||||
++sc->arpcom.ac_if.if_ipackets;
|
||||
|
||||
if (sc->arpcom.ac_if.if_bpf)
|
||||
{
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode if
|
||||
* there are no BPF listeners. And 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) &&
|
||||
(eh->ether_dhost[0] & 1) == 0 &&
|
||||
bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost)) != 0 &&
|
||||
bcmp(eh->ether_dhost, etherbroadcastaddr,
|
||||
sizeof(eh->ether_dhost)) != 0) {
|
||||
m_freem(m);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove link layer addresses and whatnot.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1851,23 +1851,6 @@ static void ti_rxeof(sc)
|
|||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
#include <sys/queue.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "opt_bdg.h"
|
||||
#define NBPFILTER 1
|
||||
|
||||
#include <net/if.h>
|
||||
|
|
@ -62,10 +61,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -932,51 +927,6 @@ epic_rx_done(sc)
|
|||
bpf_mtap( EPIC_BPFTAP_ARG(&sc->sc_if), m );
|
||||
#endif /* NBPFILTER > 0 */
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp == BDG_DROP) {
|
||||
if (m)
|
||||
m_free(m);
|
||||
continue; /* and drop */
|
||||
}
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST &&
|
||||
bdg_ifp != BDG_MCAST) {
|
||||
if (m)
|
||||
m_free(m);
|
||||
continue; /* and drop */
|
||||
}
|
||||
/* all others accepted locally */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__FreeBSD__)
|
||||
/*
|
||||
* This deserves explanation
|
||||
* If the bridge is _on_, then the following check
|
||||
* must not be done because occasionally the bridge
|
||||
* gets packets that are local but have the ethernet
|
||||
* address of one of the other interfaces.
|
||||
*
|
||||
* But if the bridge is off, then we have to drop
|
||||
* stuff that came in just via bpf.
|
||||
*
|
||||
* In OpenBSD such filter stands in ether_input. (?)
|
||||
*/
|
||||
/* Accept only our packets, broadcasts and multicasts */
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge)
|
||||
#endif
|
||||
if ((eh->ether_dhost[0] & 1) == 0 &&
|
||||
bcmp(eh->ether_dhost,sc->sc_macaddr,ETHER_ADDR_LEN)){
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Second mbuf holds packet ifself */
|
||||
m->m_pkthdr.len = m->m_len = len - sizeof(struct ether_header);
|
||||
m->m_data += sizeof( struct ether_header );
|
||||
|
|
|
|||
|
|
@ -96,26 +96,8 @@ Static void usbintr()
|
|||
q = (struct usb_qdat *)m->m_pkthdr.rcvif;
|
||||
ifp = q->ifp;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost,
|
||||
((struct arpcom *)ifp->if_softc)->ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
done:
|
||||
|
||||
/* Re-arm the receiver */
|
||||
(*q->if_rxstart)(ifp);
|
||||
|
|
|
|||
|
|
@ -75,11 +75,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif /* BRIDGE */
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -1045,37 +1040,6 @@ static void vr_rxeof(sc)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) &&
|
||||
(bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* BRIDGE */
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -738,27 +738,18 @@ again:
|
|||
/* We assume the header fit entirely in one mbuf. */
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface.
|
||||
* If so, hand off the raw packet to BPF.
|
||||
*/
|
||||
if (sc->arpcom.ac_if.if_bpf) {
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: Some cards seem to be in promiscous mode all the time.
|
||||
* we need to make sure we only get our own stuff always.
|
||||
* bleah!
|
||||
*/
|
||||
|
||||
if ((eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
|
||||
bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost)) != 0) {
|
||||
if ((eh->ether_dhost[0] & 1) == 0 /* !mcast and !bcast */
|
||||
&& bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) != 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
/* We assume the header fit entirely in one mbuf. */
|
||||
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
||||
|
|
|
|||
|
|
@ -430,25 +430,12 @@ static void wi_rxeof(sc)
|
|||
|
||||
ifp->if_ipackets++;
|
||||
|
||||
/* Handle BPF listeners. */
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive packet. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
#ifdef WICACHE
|
||||
wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
|
||||
#endif
|
||||
ether_input(ifp, eh, m);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void wi_txeof(sc, status)
|
||||
|
|
|
|||
|
|
@ -1074,28 +1074,11 @@ wlread(int unit, u_short fd_p)
|
|||
|
||||
m->m_pkthdr.len = clen;
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface. If so, hand off
|
||||
* the raw packet to bpf.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
/* bpf assumes header is in mbufs. It isn't. We can
|
||||
* fool it without allocating memory as follows.
|
||||
* Trick borrowed from if_ie.c
|
||||
*/
|
||||
struct mbuf m0;
|
||||
m0.m_len = sizeof eh;
|
||||
m0.m_data = (caddr_t) &eh;
|
||||
m0.m_next = m;
|
||||
|
||||
bpf_mtap(ifp, &m0);
|
||||
|
||||
}
|
||||
/*
|
||||
* If hw is in promiscuous mode (note that I said hardware, not if
|
||||
* IFF_PROMISC is set in ifnet flags), then if this is a unicast
|
||||
* packet and the MAC dst is not us, drop it. This check was formerly
|
||||
* inside the bpf if, above, but IFF_MULTI causes hw promisc without
|
||||
* packet and the MAC dst is not us, drop it. This check in normally
|
||||
* inside ether_input(), but IFF_MULTI causes hw promisc without
|
||||
* a bpf listener, so this is wrong.
|
||||
* Greg Troxel <gdt@ir.bbn.com>, 1998-08-07
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1050,29 +1050,7 @@ xe_intr(void *xscp)
|
|||
bus_space_read_multi_2(scp->bst, scp->bsh, XE_EDP,
|
||||
(u_int16_t *) ehp, len >> 1);
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface. If so, hand
|
||||
* off the raw packet to bpf.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
#if XE_DEBUG > 1
|
||||
device_printf(scp->dev, "passing input packet to BPF\n");
|
||||
#endif
|
||||
bpf_mtap(ifp, mbp);
|
||||
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode if there
|
||||
* are no BPF listeners. And if we are in promiscuous mode, we
|
||||
* have to check if this packet is really ours.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_PROMISC) &&
|
||||
bcmp(ehp->ether_dhost, scp->arpcom.ac_enaddr, sizeof(ehp->ether_dhost)) != 0 &&
|
||||
(rsr & XE_RSR_PHYS_PACKET)) {
|
||||
m_freem(mbp);
|
||||
mbp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Deliver packet to upper layers */
|
||||
if (mbp != NULL) {
|
||||
mbp->m_pkthdr.len = mbp->m_len = len - ETHER_HDR_LEN;
|
||||
mbp->m_data += ETHER_HDR_LEN; /* Strip off Ethernet header */
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static void el_stop(void *);
|
|||
static int el_xmit(struct el_softc *,int);
|
||||
static ointhand2_t elintr;
|
||||
static __inline void elread(struct el_softc *,caddr_t,int);
|
||||
static struct mbuf *elget(caddr_t,int,int,struct ifnet *);
|
||||
static struct mbuf *elget(caddr_t,int,struct ifnet *);
|
||||
static __inline void el_hardreset(void *);
|
||||
|
||||
/* isa_driver structure for autoconf */
|
||||
|
|
@ -424,32 +424,9 @@ elread(struct el_softc *sc,caddr_t buf,int len)
|
|||
eh = (struct ether_header *)buf;
|
||||
|
||||
/*
|
||||
* Check if there's a bpf filter listening on this interface.
|
||||
* If so, hand off the raw packet to bpf.
|
||||
* Put packet into an mbuf chain
|
||||
*/
|
||||
if(sc->arpcom.ac_if.if_bpf) {
|
||||
bpf_tap(&sc->arpcom.ac_if, buf,
|
||||
len + sizeof(struct ether_header));
|
||||
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode if
|
||||
* there are no bpf listeners. And if el are in promiscuous
|
||||
* mode, el have to check if this packet is really ours.
|
||||
*
|
||||
* This test does not support multicasts.
|
||||
*/
|
||||
if((sc->arpcom.ac_if.if_flags & IFF_PROMISC)
|
||||
&& bcmp(eh->ether_dhost,sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost)) != 0
|
||||
&& bcmp(eh->ether_dhost,etherbroadcastaddr,
|
||||
sizeof(eh->ether_dhost)) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pull packet off interface.
|
||||
*/
|
||||
m = elget(buf,len,0,&sc->arpcom.ac_if);
|
||||
m = elget(buf,len,&sc->arpcom.ac_if);
|
||||
if(m == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -557,27 +534,21 @@ elintr(int unit)
|
|||
* Pull read data off a interface.
|
||||
* Len is length of data, with local net header stripped.
|
||||
*/
|
||||
struct mbuf *
|
||||
elget(buf, totlen, off0, ifp)
|
||||
static struct mbuf *
|
||||
elget(buf, totlen, ifp)
|
||||
caddr_t buf;
|
||||
int totlen, off0;
|
||||
int totlen;
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct mbuf *top, **mp, *m;
|
||||
int off = off0, len;
|
||||
register caddr_t cp = buf;
|
||||
int len;
|
||||
register caddr_t cp;
|
||||
char *epkt;
|
||||
|
||||
buf += sizeof(struct ether_header);
|
||||
cp = buf;
|
||||
epkt = cp + totlen;
|
||||
|
||||
|
||||
if (off) {
|
||||
cp += off + 2 * sizeof(u_short);
|
||||
totlen -= 2 * sizeof(u_short);
|
||||
}
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == 0)
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
* cons of multiple frame transmission.
|
||||
* o To test IPX codes.
|
||||
* o To test FreeBSD3.0-current.
|
||||
* o To test BRIDGE codes.
|
||||
*/
|
||||
|
||||
#include "fe.h"
|
||||
|
|
@ -92,10 +91,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
|
@ -3819,7 +3814,7 @@ fe_ioctl ( struct ifnet * ifp, u_long command, caddr_t data )
|
|||
|
||||
/*
|
||||
* Retrieve packet from receive buffer and send to the next level up via
|
||||
* ether_input(). If there is a BPF listener, give a copy to BPF, too.
|
||||
* ether_input().
|
||||
* Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
|
||||
*/
|
||||
static int
|
||||
|
|
@ -3897,61 +3892,6 @@ fe_get_packet ( struct fe_softc * sc, u_short len )
|
|||
insw( sc->ioaddr[ FE_BMPR8 ], eh, ( len + 1 ) >> 1 );
|
||||
}
|
||||
|
||||
#define ETHER_ADDR_IS_MULTICAST(A) (*(char *)(A) & 1)
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface.
|
||||
* If it is, hand off the raw packet to bpf.
|
||||
*/
|
||||
if ( sc->sc_if.if_bpf ) {
|
||||
bpf_mtap( &sc->sc_if, m );
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *ifp;
|
||||
|
||||
ifp = bridge_in(m);
|
||||
if (ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
return 0;
|
||||
}
|
||||
if (ifp != BDG_LOCAL)
|
||||
bdg_forward(&m, ifp); /* not local, need forwarding */
|
||||
if (ifp == BDG_LOCAL || ifp == BDG_BCAST || ifp == BDG_MCAST)
|
||||
goto getit;
|
||||
/* not local and not multicast, just drop it */
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure this packet is (or may be) directed to us.
|
||||
* That is, the packet is either unicasted to our address,
|
||||
* or broad/multi-casted. If any other packets are
|
||||
* received, it is an indication of an error -- probably
|
||||
* 86960 is in a wrong operation mode.
|
||||
* Promiscuous mode is an exception. Under the mode, all
|
||||
* packets on the media must be received. (We must have
|
||||
* programmed the 86960 so.)
|
||||
*/
|
||||
|
||||
if ( ( sc->sc_if.if_flags & IFF_PROMISC )
|
||||
&& !ETHER_ADDR_IS_MULTICAST( eh->ether_dhost )
|
||||
&& bcmp( eh->ether_dhost, sc->sc_enaddr, ETHER_ADDR_LEN ) != 0 ) {
|
||||
/*
|
||||
* The packet was not for us. This is normal since
|
||||
* we are now in promiscuous mode. Just drop the packet.
|
||||
*/
|
||||
m_freem( m );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
/* Strip off the Ethernet header. */
|
||||
m->m_pkthdr.len -= sizeof ( struct ether_header );
|
||||
m->m_len -= sizeof ( struct ether_header );
|
||||
|
|
|
|||
|
|
@ -203,9 +203,6 @@ struct le_softc {
|
|||
le_mcbits_t *le_mctbl; /* pointer to multicast table */
|
||||
const char *le_prodname; /* product name DE20x-xx */
|
||||
u_char le_hwaddr[6]; /* local copy of hwaddr */
|
||||
unsigned le_scast_drops; /* singlecast drops */
|
||||
unsigned le_mcast_drops; /* multicast drops */
|
||||
unsigned le_bcast_drops; /* broadcast drops */
|
||||
union {
|
||||
#if !defined(LE_NOLEMAC)
|
||||
struct le_lemac_info un_lemac; /* LEMAC specific information */
|
||||
|
|
@ -394,27 +391,6 @@ le_input(
|
|||
}
|
||||
MEMCPY(&eh, seg1, sizeof(eh));
|
||||
|
||||
if (sc->le_if.if_bpf != NULL && seg2 == NULL) {
|
||||
bpf_tap(&sc->le_if, seg1, total_len);
|
||||
/*
|
||||
* If this is single cast but not to us
|
||||
* drop it!
|
||||
*/
|
||||
if ((eh.ether_dhost[0] & 1) == 0) {
|
||||
if (!LE_ADDREQUAL(eh.ether_dhost, sc->le_ac.ac_enaddr)) {
|
||||
sc->le_scast_drops++;
|
||||
return;
|
||||
}
|
||||
} else if ((sc->le_flags & IFF_MULTICAST) == 0) {
|
||||
sc->le_mcast_drops++;
|
||||
return;
|
||||
} else if (sc->le_flags & LE_BRDCSTONLY) {
|
||||
if (!LE_ADDRBRDCST(eh.ether_dhost)) {
|
||||
sc->le_bcast_drops++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
seg1 += sizeof(eh); total_len -= sizeof(eh); len1 -= sizeof(eh);
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
|
|
@ -449,30 +425,6 @@ le_input(
|
|||
MEMCPY(mtod(m, caddr_t), seg1, len1);
|
||||
if (seg2 != NULL)
|
||||
MEMCPY(mtod(m, caddr_t) + len1, seg2, total_len - len1);
|
||||
if (sc->le_if.if_bpf != NULL && seg2 != NULL) {
|
||||
bpf_mtap(&sc->le_if, m);
|
||||
/*
|
||||
* If this is single cast but not to us
|
||||
* drop it!
|
||||
*/
|
||||
if ((eh.ether_dhost[0] & 1) == 0) {
|
||||
if (!LE_ADDREQUAL(eh.ether_dhost, sc->le_ac.ac_enaddr)) {
|
||||
sc->le_scast_drops++;
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
} else if ((sc->le_flags & IFF_MULTICAST) == 0) {
|
||||
sc->le_mcast_drops++;
|
||||
m_freem(m);
|
||||
return;
|
||||
} else if (sc->le_flags & LE_BRDCSTONLY) {
|
||||
if (!LE_ADDRBRDCST(eh.ether_dhost)) {
|
||||
sc->le_bcast_drops++;
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ether_input(&sc->le_if, &eh, m);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,11 +84,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include <machine/clock.h>
|
||||
#endif
|
||||
|
|
@ -596,56 +591,14 @@ lnc_rint(struct lnc_softc *sc)
|
|||
*/
|
||||
head->m_pkthdr.rcvif = &sc->arpcom.ac_if;
|
||||
head->m_pkthdr.len = pkt_len ;
|
||||
|
||||
/*
|
||||
* BPF expects the ether header to be in the first
|
||||
* mbuf of the chain so point eh at the right place
|
||||
* but don't increment the mbuf pointers before
|
||||
* the bpf tap.
|
||||
*/
|
||||
|
||||
eh = (struct ether_header *) head->m_data;
|
||||
|
||||
if (sc->arpcom.ac_if.if_bpf)
|
||||
bpf_mtap(&sc->arpcom.ac_if, head);
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
/* Skip over the ether header */
|
||||
head->m_data += sizeof *eh;
|
||||
head->m_len -= sizeof *eh;
|
||||
head->m_pkthdr.len -= sizeof *eh;
|
||||
|
||||
bdg_ifp = bridge_in(head);
|
||||
if (bdg_ifp == BDG_DROP)
|
||||
m_freem(head);
|
||||
else {
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&head, bdg_ifp);
|
||||
if ( bdg_ifp == BDG_LOCAL ||
|
||||
bdg_ifp == BDG_BCAST ||
|
||||
bdg_ifp == BDG_MCAST )
|
||||
goto getit;
|
||||
else if (head)
|
||||
m_freem(head);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
/* Check this packet is really for us */
|
||||
|
||||
if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
|
||||
!(eh->ether_dhost[0] & 1) && /* Broadcast and multicast */
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost))))
|
||||
m_freem(head);
|
||||
else
|
||||
{
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
/* Skip over the ether header */
|
||||
head->m_data += sizeof *eh;
|
||||
head->m_len -= sizeof *eh;
|
||||
head->m_pkthdr.len -= sizeof *eh;
|
||||
|
||||
ether_input(&sc->arpcom.ac_if, eh, head);
|
||||
}
|
||||
ether_input(&sc->arpcom.ac_if, eh, head);
|
||||
|
||||
} else {
|
||||
int unit = sc->arpcom.ac_if.if_unit;
|
||||
|
|
|
|||
|
|
@ -1093,8 +1093,7 @@ rdp_rint(struct rdp_softc *sc)
|
|||
|
||||
/*
|
||||
* Retreive packet from NIC memory and send to the next level up via
|
||||
* ether_input(). If there is a BPF listener, give a copy to BPF,
|
||||
* too.
|
||||
* ether_input().
|
||||
*/
|
||||
static void
|
||||
rdp_get_packet(struct rdp_softc *sc, unsigned len)
|
||||
|
|
@ -1153,26 +1152,6 @@ rdp_get_packet(struct rdp_softc *sc, unsigned len)
|
|||
outb(sc->baseaddr + lpt_control, Ctrl_SelData);
|
||||
WrNib(sc, CMR1, CMR1_RDPAC);
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface. If so, hand off
|
||||
* the raw packet to bpf.
|
||||
*/
|
||||
if (sc->arpcom.ac_if.if_bpf) {
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
|
||||
/*
|
||||
* Note that the interface cannot be in promiscuous mode if
|
||||
* there are no BPF listeners. And 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) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove link layer address.
|
||||
*/
|
||||
|
|
@ -1180,7 +1159,6 @@ rdp_get_packet(struct rdp_softc *sc, unsigned len)
|
|||
m->m_data += sizeof(struct ether_header);
|
||||
|
||||
ether_input(&sc->arpcom.ac_if, eh, m);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -430,25 +430,12 @@ static void wi_rxeof(sc)
|
|||
|
||||
ifp->if_ipackets++;
|
||||
|
||||
/* Handle BPF listeners. */
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive packet. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
#ifdef WICACHE
|
||||
wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
|
||||
#endif
|
||||
ether_input(ifp, eh, m);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void wi_txeof(sc, status)
|
||||
|
|
|
|||
|
|
@ -1074,28 +1074,11 @@ wlread(int unit, u_short fd_p)
|
|||
|
||||
m->m_pkthdr.len = clen;
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface. If so, hand off
|
||||
* the raw packet to bpf.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
/* bpf assumes header is in mbufs. It isn't. We can
|
||||
* fool it without allocating memory as follows.
|
||||
* Trick borrowed from if_ie.c
|
||||
*/
|
||||
struct mbuf m0;
|
||||
m0.m_len = sizeof eh;
|
||||
m0.m_data = (caddr_t) &eh;
|
||||
m0.m_next = m;
|
||||
|
||||
bpf_mtap(ifp, &m0);
|
||||
|
||||
}
|
||||
/*
|
||||
* If hw is in promiscuous mode (note that I said hardware, not if
|
||||
* IFF_PROMISC is set in ifnet flags), then if this is a unicast
|
||||
* packet and the MAC dst is not us, drop it. This check was formerly
|
||||
* inside the bpf if, above, but IFF_MULTI causes hw promisc without
|
||||
* packet and the MAC dst is not us, drop it. This check in normally
|
||||
* inside ether_input(), but IFF_MULTI causes hw promisc without
|
||||
* a bpf listener, so this is wrong.
|
||||
* Greg Troxel <gdt@ir.bbn.com>, 1998-08-07
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -31,9 +31,8 @@
|
|||
* A bridging table holds the source MAC address/dest. interface for each
|
||||
* known node. The table is indexed using an hash of the source address.
|
||||
*
|
||||
* Input packets are tapped near the end of the input routine in each
|
||||
* driver (near the call to bpf_mtap, or before the call to ether_input)
|
||||
* and analysed calling bridge_in(). Depending on the result, the packet
|
||||
* Input packets are tapped near the beginning of ether_input(), and
|
||||
* analysed by calling bridge_in(). Depending on the result, the packet
|
||||
* can be forwarded to one or more output interfaces using bdg_forward(),
|
||||
* and/or sent to the upper layer (e.g. in case of multicast).
|
||||
*
|
||||
|
|
@ -163,7 +162,7 @@ static struct bdg_softc *ifp2sc = NULL ;
|
|||
#define IFP_CHK(ifp, x) \
|
||||
if (ifp2sc[ifp->if_index].magic != 0xDEADBEEF) { x ; }
|
||||
|
||||
#define SAMECLUSTER(ifp,src,eh) \
|
||||
#define SAMECLUSTER(ifp,src) \
|
||||
(src == NULL || CLUSTER(ifp) == CLUSTER(src) )
|
||||
|
||||
/*
|
||||
|
|
@ -473,11 +472,9 @@ bdginit(void *dummy)
|
|||
|
||||
/*
|
||||
* bridge_in() is invoked to perform bridging decision on input packets.
|
||||
*
|
||||
* On Input:
|
||||
* m packet to be bridged. The mbuf need not to hold the
|
||||
* whole packet, only the first 14 bytes suffice. We
|
||||
* assume them to be contiguous. No alignment assumptions
|
||||
* because they are not a problem on i386 class machines.
|
||||
* eh Ethernet header of the incoming packet.
|
||||
*
|
||||
* On Return: destination of packet, one of
|
||||
* BDG_BCAST broadcast
|
||||
|
|
@ -490,16 +487,12 @@ bdginit(void *dummy)
|
|||
* to fetch more of the packet, or simply drop it completely.
|
||||
*/
|
||||
|
||||
|
||||
struct ifnet *
|
||||
bridge_in(struct mbuf *m)
|
||||
bridge_in(struct ifnet *ifp, struct ether_header *eh)
|
||||
{
|
||||
int index;
|
||||
struct ifnet *ifp = m->m_pkthdr.rcvif, *dst , *old ;
|
||||
struct ifnet *dst , *old ;
|
||||
int dropit = MUTED(ifp) ;
|
||||
struct ether_header *eh;
|
||||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/*
|
||||
* hash the source address
|
||||
|
|
@ -545,7 +538,7 @@ bridge_in(struct mbuf *m)
|
|||
bcopy(eh->ether_shost, bdg_table[index].etheraddr, 6);
|
||||
bdg_table[index].name = ifp ;
|
||||
}
|
||||
dst = bridge_dst_lookup(m);
|
||||
dst = bridge_dst_lookup(eh);
|
||||
/* Return values:
|
||||
* BDG_BCAST, BDG_MCAST, BDG_LOCAL, BDG_UNKNOWN, BDG_DROP, ifp.
|
||||
* For muted interfaces, the first 3 are changed in BDG_LOCAL,
|
||||
|
|
@ -599,7 +592,7 @@ bridge_in(struct mbuf *m)
|
|||
* *m0 -- pointer to the packet (NULL if still existent)
|
||||
*/
|
||||
int
|
||||
bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
||||
bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst)
|
||||
{
|
||||
struct ifnet *src = (*m0)->m_pkthdr.rcvif; /* could be NULL in output */
|
||||
struct ifnet *ifp, *last = NULL ;
|
||||
|
|
@ -608,8 +601,6 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
int once = 0; /* loop only once */
|
||||
struct mbuf *m ;
|
||||
|
||||
struct ether_header *eh = mtod(*m0, struct ether_header *); /* XXX */
|
||||
|
||||
if (dst == BDG_DROP) { /* this should not happen */
|
||||
printf("xx bdg_forward for BDG_DROP\n");
|
||||
m_freem(*m0) ;
|
||||
|
|
@ -642,7 +633,6 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
* ethernet header.
|
||||
*/
|
||||
if (ip_fw_chk_ptr) {
|
||||
u_int16_t dummy = 0 ;
|
||||
struct ip_fw_chain *rule = NULL ;
|
||||
int off;
|
||||
struct ip *ip ;
|
||||
|
|
@ -658,7 +648,6 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
(*m0) = m = m->m_next ;
|
||||
|
||||
src = m->m_pkthdr.rcvif; /* could be NULL in output */
|
||||
eh = mtod(m, struct ether_header *); /* XXX */
|
||||
canfree = 1 ; /* for sure, a copy is not needed later. */
|
||||
goto forward; /* HACK! I should obey the fw_one_pass */
|
||||
}
|
||||
|
|
@ -680,7 +669,7 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
* Need to make a copy (and for good measure, make sure that
|
||||
* the header is contiguous). The original is still in *m0
|
||||
*/
|
||||
int needed = min(MHLEN, 14+max_protohdr) ;
|
||||
int needed = min(MHLEN, max_protohdr) ;
|
||||
needed = min(needed, (*m0)->m_len ) ;
|
||||
|
||||
m = m_copypacket( (*m0), M_DONTWAIT);
|
||||
|
|
@ -688,8 +677,7 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
printf("-- bdg: m_copypacket failed.\n") ;
|
||||
return ENOBUFS ;
|
||||
}
|
||||
m = m_pullup(m, needed) ;
|
||||
if ( m == NULL ) {
|
||||
if (m->m_len < needed && (m = m_pullup(m, needed)) == NULL) {
|
||||
printf("-- bdg: pullup failed.\n") ;
|
||||
return ENOBUFS ;
|
||||
}
|
||||
|
|
@ -699,8 +687,7 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
* before calling the firewall, swap fields the same as IP does.
|
||||
* here we assume the pkt is an IP one and the header is contiguous
|
||||
*/
|
||||
eh = mtod(m, struct ether_header *);
|
||||
ip = (struct ip *)(eh + 1 ) ;
|
||||
ip = mtod(m, struct ip *);
|
||||
NTOHS(ip->ip_len);
|
||||
NTOHS(ip->ip_id);
|
||||
NTOHS(ip->ip_off);
|
||||
|
|
@ -709,7 +696,7 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
* The third parameter to the firewall code is the dst. interface.
|
||||
* Since we apply checks only on input pkts we use NULL.
|
||||
*/
|
||||
off = (*ip_fw_chk_ptr)(NULL, 0, NULL, &dummy, &m, &rule, NULL) ;
|
||||
off = (*ip_fw_chk_ptr)(&ip, 0, NULL, NULL, &m, &rule, NULL);
|
||||
|
||||
if (m == NULL) { /* pkt discarded by firewall */
|
||||
/*
|
||||
|
|
@ -724,11 +711,9 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
|
|||
|
||||
/*
|
||||
* If we get here, the firewall has passed the pkt, but the
|
||||
* mbuf pointer might have changed. Restore eh, ip, and the
|
||||
* fields NTOHS()'d. Then, if canfree==1, also restore *m0.
|
||||
* mbuf pointer might have changed. Restore the fields NTOHS()'d.
|
||||
* Then, if canfree==1, also restore *m0.
|
||||
*/
|
||||
eh = mtod(m, struct ether_header *);
|
||||
ip = (struct ip *)(eh + 1 ) ;
|
||||
HTONS(ip->ip_len);
|
||||
HTONS(ip->ip_id);
|
||||
HTONS(ip->ip_off);
|
||||
|
|
@ -774,11 +759,10 @@ forward:
|
|||
* but better than having packets corrupt!
|
||||
*/
|
||||
if (canfree == 0 ) {
|
||||
int needed = min(MHLEN, 14+max_protohdr) ;
|
||||
int needed = min(MHLEN, max_protohdr) ;
|
||||
needed = min(needed, (*m0)->m_len ) ;
|
||||
|
||||
*m0 = m_pullup( *m0, needed) ;
|
||||
if ( *m0 == NULL ) {
|
||||
if ((*m0)->m_len < needed && (*m0 = m_pullup(*m0, needed)) == NULL) {
|
||||
printf("-- bdg: pullup failed.\n") ;
|
||||
return ENOBUFS ;
|
||||
}
|
||||
|
|
@ -795,9 +779,13 @@ forward:
|
|||
return ENOBUFS ; /* the original is still there... */
|
||||
}
|
||||
/*
|
||||
* Last part of ether_output: queue pkt and start
|
||||
* Last part of ether_output: add header, queue pkt and start
|
||||
* output if interface not yet active.
|
||||
*/
|
||||
M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return ENOBUFS;
|
||||
bcopy(eh, mtod(m, struct ether_header *), ETHER_HDR_LEN);
|
||||
s = splimp();
|
||||
if (IF_QFULL(&last->if_snd)) {
|
||||
IF_DROP(&last->if_snd);
|
||||
|
|
@ -828,7 +816,7 @@ forward:
|
|||
! IF_QFULL(&ifp->if_snd) &&
|
||||
(ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
|
||||
(IFF_UP|IFF_RUNNING) &&
|
||||
SAMECLUSTER(ifp, src, eh) && !MUTED(ifp) )
|
||||
SAMECLUSTER(ifp, src) && !MUTED(ifp) )
|
||||
last = ifp ;
|
||||
ifp = ifp->if_link.tqe_next ;
|
||||
if (ifp == NULL)
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ extern int bdg_ports ;
|
|||
#define HASH_FN(addr) ( \
|
||||
ntohs( ((short *)addr)[1] ^ ((short *)addr)[2] ) & (HASH_SIZE -1))
|
||||
|
||||
struct ifnet *bridge_in(struct mbuf *m);
|
||||
struct ifnet *bridge_in(struct ifnet *ifp, struct ether_header *eh);
|
||||
/* bdg_forward frees the mbuf if necessary, returning null */
|
||||
int bdg_forward (struct mbuf **m, struct ifnet *dst);
|
||||
int bdg_forward(struct mbuf **m0, struct ether_header *eh, struct ifnet *dst);
|
||||
|
||||
#ifdef __i386__
|
||||
#define BDG_MATCH(a,b) ( \
|
||||
|
|
@ -109,9 +109,8 @@ struct bdg_stats {
|
|||
*/
|
||||
static __inline
|
||||
struct ifnet *
|
||||
bridge_dst_lookup(struct mbuf *m)
|
||||
bridge_dst_lookup(struct ether_header *eh)
|
||||
{
|
||||
struct ether_header *eh = mtod(m, struct ether_header *);
|
||||
struct ifnet *dst ;
|
||||
int index ;
|
||||
u_char *eth_addr = bdg_addresses ;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include <net/if_llc.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <netinet/in.h>
|
||||
|
|
@ -365,19 +366,22 @@ ether_output(ifp, m, dst, rt0)
|
|||
return (0); /* XXX */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct mbuf *m0 = m ;
|
||||
struct ether_header hdr;
|
||||
|
||||
if (m->m_pkthdr.rcvif)
|
||||
m->m_pkthdr.rcvif = NULL ;
|
||||
ifp = bridge_dst_lookup(m);
|
||||
bdg_forward(&m0, ifp);
|
||||
if (m0)
|
||||
m_freem(m0);
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
bcopy(mtod(m, struct ether_header *), &hdr, ETHER_HDR_LEN);
|
||||
m_adj(m, ETHER_HDR_LEN);
|
||||
ifp = bridge_dst_lookup(&hdr);
|
||||
bdg_forward(&m, &hdr, ifp);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = splimp();
|
||||
/*
|
||||
* Queue message on interface, and start output if interface
|
||||
|
|
@ -421,6 +425,55 @@ ether_input(ifp, eh, m)
|
|||
register struct llc *l;
|
||||
#endif
|
||||
|
||||
/* Check for a BPF tap */
|
||||
if (ifp->if_bpf != NULL) {
|
||||
struct m_hdr mh;
|
||||
|
||||
/* This kludge is OK; BPF treats the "mbuf" as read-only */
|
||||
mh.mh_next = m;
|
||||
mh.mh_data = (char *)eh;
|
||||
mh.mh_len = ETHER_HDR_LEN;
|
||||
bpf_mtap(ifp, (struct mbuf *)&mh);
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
/* Check for bridging mode */
|
||||
if (do_bridge) {
|
||||
struct ifnet *bif;
|
||||
|
||||
/* Check with bridging code */
|
||||
if ((bif = bridge_in(ifp, eh)) == BDG_DROP) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
if (bif != BDG_LOCAL)
|
||||
bdg_forward(&m, eh, bif); /* needs forwarding */
|
||||
if (bif == BDG_LOCAL
|
||||
|| bif == BDG_BCAST
|
||||
|| bif == BDG_MCAST)
|
||||
goto recvLocal; /* receive locally */
|
||||
|
||||
/* If not local and not multicast, just drop it */
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Discard packet if upper layers shouldn't see it. This should
|
||||
only happen when the interface is in promiscuous mode. */
|
||||
if ((ifp->if_flags & IFF_PROMISC) != 0
|
||||
&& (eh->ether_dhost[0] & 1) == 0
|
||||
&& bcmp(eh->ether_dhost,
|
||||
IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
recvLocal:
|
||||
#endif
|
||||
/* Discard packet if interface is not up */
|
||||
if ((ifp->if_flags & IFF_UP) == 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -305,19 +305,6 @@ vlan_input_tag(struct ether_header *eh, struct mbuf *m, u_int16_t t)
|
|||
*/
|
||||
m->m_pkthdr.rcvif = &ifv->ifv_if;
|
||||
|
||||
if (ifv->ifv_if.if_bpf) {
|
||||
/*
|
||||
* Do the usual BPF fakery. Note that we don't support
|
||||
* promiscuous mode here, since it would require the
|
||||
* drivers to know about VLANs and we're not ready for
|
||||
* that yet.
|
||||
*/
|
||||
struct mbuf m0;
|
||||
m0.m_next = m;
|
||||
m0.m_len = sizeof(struct ether_header);
|
||||
m0.m_data = (char *)eh;
|
||||
bpf_mtap(&ifv->ifv_if, &m0);
|
||||
}
|
||||
ifv->ifv_if.if_ipackets++;
|
||||
ether_input(&ifv->ifv_if, eh, m);
|
||||
return 0;
|
||||
|
|
@ -355,19 +342,6 @@ vlan_input(struct ether_header *eh, struct mbuf *m)
|
|||
m->m_len -= EVL_ENCAPLEN;
|
||||
m->m_pkthdr.len -= EVL_ENCAPLEN;
|
||||
|
||||
if (ifv->ifv_if.if_bpf) {
|
||||
/*
|
||||
* Do the usual BPF fakery. Note that we don't support
|
||||
* promiscuous mode here, since it would require the
|
||||
* drivers to know about VLANs and we're not ready for
|
||||
* that yet.
|
||||
*/
|
||||
struct mbuf m0;
|
||||
m0.m_next = m;
|
||||
m0.m_len = sizeof(struct ether_header);
|
||||
m0.m_data = (char *)eh;
|
||||
bpf_mtap(&ifv->ifv_if, &m0);
|
||||
}
|
||||
ifv->ifv_if.if_ipackets++;
|
||||
ether_input(&ifv->ifv_if, eh, m);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -312,7 +312,16 @@ transmit_event(struct dn_pipe *pipe)
|
|||
#ifdef BRIDGE
|
||||
case DN_TO_BDG_FWD : {
|
||||
struct mbuf *m = (struct mbuf *)pkt ;
|
||||
bdg_forward(&m, pkt->ifp);
|
||||
struct ether_header hdr;
|
||||
|
||||
if (m->m_len < ETHER_HDR_LEN
|
||||
&& (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
|
||||
m_freem(m);
|
||||
break;
|
||||
}
|
||||
bcopy(mtod(m, struct ether_header *), &hdr, ETHER_HDR_LEN);
|
||||
m_adj(m, ETHER_HDR_LEN);
|
||||
bdg_forward(&m, &hdr, pkt->ifp);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,148 +389,146 @@ static void
|
|||
ipfw_report(struct ip_fw *f, struct ip *ip,
|
||||
struct ifnet *rif, struct ifnet *oif)
|
||||
{
|
||||
if (ip) {
|
||||
struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
struct udphdr *const udp = (struct udphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
struct icmp *const icmp = (struct icmp *) ((u_int32_t *) ip + ip->ip_hl);
|
||||
u_int64_t count;
|
||||
char *action;
|
||||
char action2[32], proto[47], name[18], fragment[17];
|
||||
int len;
|
||||
struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
struct udphdr *const udp = (struct udphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
struct icmp *const icmp = (struct icmp *) ((u_int32_t *) ip + ip->ip_hl);
|
||||
u_int64_t count;
|
||||
char *action;
|
||||
char action2[32], proto[47], name[18], fragment[17];
|
||||
int len;
|
||||
|
||||
count = f ? f->fw_pcnt : ++counter;
|
||||
if ((f == NULL && fw_verbose_limit != 0 && count > fw_verbose_limit) ||
|
||||
(f && f->fw_logamount != 0 && count > f->fw_loghighest))
|
||||
return;
|
||||
count = f ? f->fw_pcnt : ++counter;
|
||||
if ((f == NULL && fw_verbose_limit != 0 && count > fw_verbose_limit) ||
|
||||
(f && f->fw_logamount != 0 && count > f->fw_loghighest))
|
||||
return;
|
||||
|
||||
/* Print command name */
|
||||
snprintf(SNPARGS(name, 0), "ipfw: %d", f ? f->fw_number : -1);
|
||||
/* Print command name */
|
||||
snprintf(SNPARGS(name, 0), "ipfw: %d", f ? f->fw_number : -1);
|
||||
|
||||
action = action2;
|
||||
if (!f)
|
||||
action = "Refuse";
|
||||
else {
|
||||
switch (f->fw_flg & IP_FW_F_COMMAND) {
|
||||
case IP_FW_F_DENY:
|
||||
action = "Deny";
|
||||
break;
|
||||
case IP_FW_F_REJECT:
|
||||
if (f->fw_reject_code == IP_FW_REJECT_RST)
|
||||
action = "Reset";
|
||||
else
|
||||
action = "Unreach";
|
||||
break;
|
||||
case IP_FW_F_ACCEPT:
|
||||
action = "Accept";
|
||||
break;
|
||||
case IP_FW_F_COUNT:
|
||||
action = "Count";
|
||||
break;
|
||||
action = action2;
|
||||
if (!f)
|
||||
action = "Refuse";
|
||||
else {
|
||||
switch (f->fw_flg & IP_FW_F_COMMAND) {
|
||||
case IP_FW_F_DENY:
|
||||
action = "Deny";
|
||||
break;
|
||||
case IP_FW_F_REJECT:
|
||||
if (f->fw_reject_code == IP_FW_REJECT_RST)
|
||||
action = "Reset";
|
||||
else
|
||||
action = "Unreach";
|
||||
break;
|
||||
case IP_FW_F_ACCEPT:
|
||||
action = "Accept";
|
||||
break;
|
||||
case IP_FW_F_COUNT:
|
||||
action = "Count";
|
||||
break;
|
||||
#ifdef IPDIVERT
|
||||
case IP_FW_F_DIVERT:
|
||||
snprintf(SNPARGS(action2, 0), "Divert %d",
|
||||
f->fw_divert_port);
|
||||
break;
|
||||
case IP_FW_F_TEE:
|
||||
snprintf(SNPARGS(action2, 0), "Tee %d",
|
||||
f->fw_divert_port);
|
||||
break;
|
||||
case IP_FW_F_DIVERT:
|
||||
snprintf(SNPARGS(action2, 0), "Divert %d",
|
||||
f->fw_divert_port);
|
||||
break;
|
||||
case IP_FW_F_TEE:
|
||||
snprintf(SNPARGS(action2, 0), "Tee %d",
|
||||
f->fw_divert_port);
|
||||
break;
|
||||
#endif
|
||||
case IP_FW_F_SKIPTO:
|
||||
snprintf(SNPARGS(action2, 0), "SkipTo %d",
|
||||
f->fw_skipto_rule);
|
||||
break;
|
||||
case IP_FW_F_SKIPTO:
|
||||
snprintf(SNPARGS(action2, 0), "SkipTo %d",
|
||||
f->fw_skipto_rule);
|
||||
break;
|
||||
#ifdef DUMMYNET
|
||||
case IP_FW_F_PIPE:
|
||||
snprintf(SNPARGS(action2, 0), "Pipe %d",
|
||||
f->fw_skipto_rule);
|
||||
break;
|
||||
case IP_FW_F_PIPE:
|
||||
snprintf(SNPARGS(action2, 0), "Pipe %d",
|
||||
f->fw_skipto_rule);
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPFIREWALL_FORWARD
|
||||
case IP_FW_F_FWD:
|
||||
if (f->fw_fwd_ip.sin_port)
|
||||
snprintf(SNPARGS(action2, 0),
|
||||
"Forward to %s:%d",
|
||||
inet_ntoa(f->fw_fwd_ip.sin_addr),
|
||||
f->fw_fwd_ip.sin_port);
|
||||
else
|
||||
snprintf(SNPARGS(action2, 0), "Forward to %s",
|
||||
inet_ntoa(f->fw_fwd_ip.sin_addr));
|
||||
break;
|
||||
case IP_FW_F_FWD:
|
||||
if (f->fw_fwd_ip.sin_port)
|
||||
snprintf(SNPARGS(action2, 0),
|
||||
"Forward to %s:%d",
|
||||
inet_ntoa(f->fw_fwd_ip.sin_addr),
|
||||
f->fw_fwd_ip.sin_port);
|
||||
else
|
||||
snprintf(SNPARGS(action2, 0), "Forward to %s",
|
||||
inet_ntoa(f->fw_fwd_ip.sin_addr));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
action = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ip->ip_p) {
|
||||
case IPPROTO_TCP:
|
||||
len = snprintf(SNPARGS(proto, 0), "TCP %s",
|
||||
inet_ntoa(ip->ip_src));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
len += snprintf(SNPARGS(proto, len), ":%d ",
|
||||
ntohs(tcp->th_sport));
|
||||
else
|
||||
len += snprintf(SNPARGS(proto, len), " ");
|
||||
len += snprintf(SNPARGS(proto, len), "%s",
|
||||
inet_ntoa(ip->ip_dst));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
snprintf(SNPARGS(proto, len), ":%d",
|
||||
ntohs(tcp->th_dport));
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
len = snprintf(SNPARGS(proto, 0), "UDP %s",
|
||||
inet_ntoa(ip->ip_src));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
len += snprintf(SNPARGS(proto, len), ":%d ",
|
||||
ntohs(udp->uh_sport));
|
||||
else
|
||||
len += snprintf(SNPARGS(proto, len), " ");
|
||||
len += snprintf(SNPARGS(proto, len), "%s",
|
||||
inet_ntoa(ip->ip_dst));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
snprintf(SNPARGS(proto, len), ":%d",
|
||||
ntohs(udp->uh_dport));
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
len = snprintf(SNPARGS(proto, 0), "ICMP:%u.%u ",
|
||||
icmp->icmp_type, icmp->icmp_code);
|
||||
else
|
||||
len = snprintf(SNPARGS(proto, 0), "ICMP ");
|
||||
len += snprintf(SNPARGS(proto, len), "%s",
|
||||
inet_ntoa(ip->ip_src));
|
||||
snprintf(SNPARGS(proto, len), " %s", inet_ntoa(ip->ip_dst));
|
||||
break;
|
||||
default:
|
||||
len = snprintf(SNPARGS(proto, 0), "P:%d %s", ip->ip_p,
|
||||
inet_ntoa(ip->ip_src));
|
||||
snprintf(SNPARGS(proto, len), " %s", inet_ntoa(ip->ip_dst));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ip->ip_off & IP_OFFMASK))
|
||||
snprintf(SNPARGS(fragment, 0), " Fragment = %d",
|
||||
ip->ip_off & IP_OFFMASK);
|
||||
else
|
||||
fragment[0] = '\0';
|
||||
if (oif)
|
||||
log(LOG_SECURITY | LOG_INFO, "%s %s %s out via %s%d%s\n",
|
||||
name, action, proto, oif->if_name, oif->if_unit, fragment);
|
||||
else if (rif)
|
||||
log(LOG_SECURITY | LOG_INFO, "%s %s %s in via %s%d%s\n", name,
|
||||
action, proto, rif->if_name, rif->if_unit, fragment);
|
||||
else
|
||||
log(LOG_SECURITY | LOG_INFO, "%s %s %s%s\n", name, action,
|
||||
proto, fragment);
|
||||
if ((f ? f->fw_logamount != 0 : 1) &&
|
||||
count == (f ? f->fw_loghighest : fw_verbose_limit))
|
||||
log(LOG_SECURITY | LOG_NOTICE,
|
||||
"ipfw: limit %d reached on entry %d\n",
|
||||
f ? f->fw_logamount : fw_verbose_limit,
|
||||
f ? f->fw_number : -1);
|
||||
default:
|
||||
action = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ip->ip_p) {
|
||||
case IPPROTO_TCP:
|
||||
len = snprintf(SNPARGS(proto, 0), "TCP %s",
|
||||
inet_ntoa(ip->ip_src));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
len += snprintf(SNPARGS(proto, len), ":%d ",
|
||||
ntohs(tcp->th_sport));
|
||||
else
|
||||
len += snprintf(SNPARGS(proto, len), " ");
|
||||
len += snprintf(SNPARGS(proto, len), "%s",
|
||||
inet_ntoa(ip->ip_dst));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
snprintf(SNPARGS(proto, len), ":%d",
|
||||
ntohs(tcp->th_dport));
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
len = snprintf(SNPARGS(proto, 0), "UDP %s",
|
||||
inet_ntoa(ip->ip_src));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
len += snprintf(SNPARGS(proto, len), ":%d ",
|
||||
ntohs(udp->uh_sport));
|
||||
else
|
||||
len += snprintf(SNPARGS(proto, len), " ");
|
||||
len += snprintf(SNPARGS(proto, len), "%s",
|
||||
inet_ntoa(ip->ip_dst));
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
snprintf(SNPARGS(proto, len), ":%d",
|
||||
ntohs(udp->uh_dport));
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
if ((ip->ip_off & IP_OFFMASK) == 0)
|
||||
len = snprintf(SNPARGS(proto, 0), "ICMP:%u.%u ",
|
||||
icmp->icmp_type, icmp->icmp_code);
|
||||
else
|
||||
len = snprintf(SNPARGS(proto, 0), "ICMP ");
|
||||
len += snprintf(SNPARGS(proto, len), "%s",
|
||||
inet_ntoa(ip->ip_src));
|
||||
snprintf(SNPARGS(proto, len), " %s", inet_ntoa(ip->ip_dst));
|
||||
break;
|
||||
default:
|
||||
len = snprintf(SNPARGS(proto, 0), "P:%d %s", ip->ip_p,
|
||||
inet_ntoa(ip->ip_src));
|
||||
snprintf(SNPARGS(proto, len), " %s", inet_ntoa(ip->ip_dst));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ip->ip_off & IP_OFFMASK))
|
||||
snprintf(SNPARGS(fragment, 0), " Fragment = %d",
|
||||
ip->ip_off & IP_OFFMASK);
|
||||
else
|
||||
fragment[0] = '\0';
|
||||
if (oif)
|
||||
log(LOG_SECURITY | LOG_INFO, "%s %s %s out via %s%d%s\n",
|
||||
name, action, proto, oif->if_name, oif->if_unit, fragment);
|
||||
else if (rif)
|
||||
log(LOG_SECURITY | LOG_INFO, "%s %s %s in via %s%d%s\n", name,
|
||||
action, proto, rif->if_name, rif->if_unit, fragment);
|
||||
else
|
||||
log(LOG_SECURITY | LOG_INFO, "%s %s %s%s\n", name, action,
|
||||
proto, fragment);
|
||||
if ((f ? f->fw_logamount != 0 : 1) &&
|
||||
count == (f ? f->fw_loghighest : fw_verbose_limit))
|
||||
log(LOG_SECURITY | LOG_NOTICE,
|
||||
"ipfw: limit %d reached on entry %d\n",
|
||||
f ? f->fw_logamount : fw_verbose_limit,
|
||||
f ? f->fw_number : -1);
|
||||
}
|
||||
|
||||
#if STATEFUL
|
||||
|
|
@ -744,7 +742,7 @@ add_dyn_rule(struct ipfw_flow_id *id, struct ipfw_flow_id *mask,
|
|||
* Type 0 (default) is a bidirectional rule
|
||||
*/
|
||||
static void
|
||||
install_state(struct ip_fw_chain *chain, struct ip **pip, struct ip *ip)
|
||||
install_state(struct ip_fw_chain *chain)
|
||||
{
|
||||
struct ipfw_dyn_rule *q ;
|
||||
u_long type = ((struct ip_fw_ext *)chain->rule)->dyn_type ;
|
||||
|
|
@ -801,14 +799,11 @@ lookup_next_rule(struct ip_fw_chain *me)
|
|||
* Parameters:
|
||||
*
|
||||
* pip Pointer to packet header (struct ip **)
|
||||
* bridge_ipfw extension: pip = NULL means a complete ethernet packet
|
||||
* including ethernet header in the mbuf. Other fields
|
||||
* are ignored/invalid.
|
||||
*
|
||||
* hlen Packet header length
|
||||
* oif Outgoing interface, or NULL if packet is incoming
|
||||
* *cookie Skip up to the first rule past this rule number;
|
||||
* upon return, non-zero port number for divert or tee
|
||||
* upon return, non-zero port number for divert or tee.
|
||||
* Special case: cookie == NULL on input for bridging.
|
||||
* *m The packet; we set to NULL when/if we nuke it.
|
||||
* *flow_id pointer to the last matching rule (in/out)
|
||||
* *next_hop socket we are forwarding to (in/out).
|
||||
|
|
@ -835,72 +830,45 @@ ip_fw_chk(struct ip **pip, int hlen,
|
|||
{
|
||||
struct ip_fw_chain *chain;
|
||||
struct ip_fw *f = NULL, *rule = NULL;
|
||||
struct ip *ip = NULL ;
|
||||
struct ip *ip = *pip;
|
||||
struct ifnet *const rif = (*m)->m_pkthdr.rcvif;
|
||||
u_short offset = 0 ;
|
||||
u_short src_port = 0, dst_port = 0;
|
||||
struct in_addr src_ip, dst_ip; /* XXX */
|
||||
u_int8_t proto= 0, flags = 0 ; /* XXX */
|
||||
u_int16_t skipto;
|
||||
u_int16_t skipto, bridgeCookie;
|
||||
|
||||
#if STATEFUL
|
||||
int dyn_checked = 0 ; /* set after dyn.rules have been checked. */
|
||||
int direction = MATCH_FORWARD ; /* dirty trick... */
|
||||
struct ipfw_dyn_rule *q = NULL ;
|
||||
#endif
|
||||
|
||||
/* Special hack for bridging (as usual) */
|
||||
if (cookie == NULL) {
|
||||
bridgeCookie = 0;
|
||||
cookie = &bridgeCookie;
|
||||
}
|
||||
|
||||
/* Grab and reset cookie */
|
||||
skipto = *cookie;
|
||||
*cookie = 0;
|
||||
|
||||
/*
|
||||
* here, pip==NULL for bridged pkts -- they include the ethernet
|
||||
* header so i have to adjust lengths accordingly
|
||||
*/
|
||||
#define PULLUP_TO(l) do { \
|
||||
int len = (pip ? (l) : (l) + 14 ); \
|
||||
if ((*m)->m_len < (len) ) { \
|
||||
if ( (*m = m_pullup(*m, (len))) == 0) \
|
||||
goto bogusfrag; \
|
||||
ip = mtod(*m, struct ip *); \
|
||||
if (pip) \
|
||||
*pip = ip ; \
|
||||
else \
|
||||
ip = (struct ip *)((char *)ip + 14);\
|
||||
offset = (ip->ip_off & IP_OFFMASK); \
|
||||
} \
|
||||
#define PULLUP_TO(len) do { \
|
||||
if ((*m)->m_len < (len)) { \
|
||||
if ((*m = m_pullup(*m, (len))) == 0) \
|
||||
goto bogusfrag; \
|
||||
ip = mtod(*m, struct ip *); \
|
||||
*pip = ip; \
|
||||
offset = (ip->ip_off & IP_OFFMASK); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
if (pip) { /* normal ip packet */
|
||||
ip = *pip;
|
||||
offset = (ip->ip_off & IP_OFFMASK);
|
||||
} else { /* bridged or non-ip packet */
|
||||
struct ether_header *eh = mtod(*m, struct ether_header *);
|
||||
switch (ntohs(eh->ether_type)) {
|
||||
case ETHERTYPE_IP :
|
||||
if ((*m)->m_len<sizeof(struct ether_header) + sizeof(struct ip))
|
||||
goto non_ip ;
|
||||
ip = (struct ip *)(eh + 1 );
|
||||
if (ip->ip_v != IPVERSION)
|
||||
goto non_ip ;
|
||||
hlen = ip->ip_hl << 2;
|
||||
if (hlen < sizeof(struct ip)) /* minimum header length */
|
||||
goto non_ip ;
|
||||
if ((*m)->m_len < 14 + hlen + 14) {
|
||||
printf("-- m_len %d, need more...\n", (*m)->m_len);
|
||||
goto non_ip ;
|
||||
}
|
||||
offset = (ip->ip_off & IP_OFFMASK);
|
||||
break ;
|
||||
default :
|
||||
non_ip: ip = NULL ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* collect parameters into local variables for faster matching.
|
||||
* Collect parameters into local variables for faster matching.
|
||||
*/
|
||||
if (ip) {
|
||||
offset = (ip->ip_off & IP_OFFMASK);
|
||||
{
|
||||
struct tcphdr *tcp;
|
||||
struct udphdr *udp;
|
||||
|
||||
|
|
@ -991,8 +959,7 @@ again:
|
|||
if (f->fw_flg & (IP_FW_F_KEEP_S|IP_FW_F_CHECK_S) &&
|
||||
dyn_checked == 0 ) {
|
||||
dyn_checked = 1 ;
|
||||
if (ip)
|
||||
q = lookup_dyn_rule(&last_pkt, &direction);
|
||||
q = lookup_dyn_rule(&last_pkt, &direction);
|
||||
if (q != NULL) {
|
||||
DEB(printf("-- dynamic match 0x%08x %d %s 0x%08x %d\n",
|
||||
(q->id.src_ip), (q->id.src_port),
|
||||
|
|
@ -1001,8 +968,7 @@ again:
|
|||
chain = q->chain ;
|
||||
f = chain->rule ;
|
||||
q->pcnt++ ;
|
||||
if (ip)
|
||||
q->bcnt += ip->ip_len;
|
||||
q->bcnt += ip->ip_len;
|
||||
goto got_match ; /* random not allowed here */
|
||||
}
|
||||
/* if this was a check-only rule, continue with next */
|
||||
|
|
@ -1010,12 +976,10 @@ again:
|
|||
continue ;
|
||||
}
|
||||
#endif /* stateful ipfw */
|
||||
/*
|
||||
* Rule only valid for bridged packets, skip if this
|
||||
* is not one of those (pip != NULL)
|
||||
*/
|
||||
if (pip != NULL && f->fw_flg & IP_FW_BRIDGED )
|
||||
continue ;
|
||||
|
||||
/* Check if rule only valid for bridged packets */
|
||||
if ((f->fw_flg & IP_FW_BRIDGED) != 0 && cookie != &bridgeCookie)
|
||||
continue;
|
||||
|
||||
if (oif) {
|
||||
/* Check direction outbound */
|
||||
|
|
@ -1026,34 +990,6 @@ again:
|
|||
if (!(f->fw_flg & IP_FW_F_IN))
|
||||
continue;
|
||||
}
|
||||
if (ip == NULL ) {
|
||||
/*
|
||||
* do relevant checks for non-ip packets:
|
||||
* after this, only goto got_match or continue
|
||||
*/
|
||||
struct ether_header *eh = mtod(*m, struct ether_header *);
|
||||
/*
|
||||
* temporary hack:
|
||||
* udp from 0.0.0.0 means this rule applies.
|
||||
* 1 src port is match ether type
|
||||
* 2 src ports (interval) is match ether type
|
||||
* 3 src ports is match ether address
|
||||
*/
|
||||
if ( f->fw_src.s_addr != 0 || f->fw_prot != IPPROTO_UDP
|
||||
|| f->fw_smsk.s_addr != 0xffffffff )
|
||||
continue;
|
||||
switch (IP_FW_GETNSRCP(f)) {
|
||||
case 1: /* match one type */
|
||||
if ( /* ( (f->fw_flg & IP_FW_F_INVSRC) != 0) ^ */
|
||||
( f->fw_uar.fw_pts[0] == ntohs(eh->ether_type) ) ) {
|
||||
goto got_match ;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
break ;
|
||||
}
|
||||
continue ;
|
||||
}
|
||||
|
||||
/* Fragments */
|
||||
if ((f->fw_flg & IP_FW_F_FRAG) && offset == 0 )
|
||||
|
|
@ -1255,14 +1191,12 @@ got_match:
|
|||
* a new dynamic entry.
|
||||
*/
|
||||
if (q == NULL && f->fw_flg & IP_FW_F_KEEP_S)
|
||||
install_state(chain, pip, ip);
|
||||
install_state(chain);
|
||||
#endif
|
||||
*flow_id = chain ; /* XXX set flow id */
|
||||
/* Update statistics */
|
||||
f->fw_pcnt += 1;
|
||||
if (ip) {
|
||||
f->fw_bcnt += ip->ip_len;
|
||||
}
|
||||
f->fw_bcnt += ip->ip_len;
|
||||
f->timestamp = time_second;
|
||||
|
||||
/* Log to console if desired */
|
||||
|
|
@ -1319,11 +1253,8 @@ got_match:
|
|||
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
/* Rule IPFW_DEFAULT_RULE should always be there and should always match */
|
||||
if (!chain)
|
||||
panic("ip_fw: chain");
|
||||
#endif
|
||||
/* Rule IPFW_DEFAULT_RULE should always be there and match */
|
||||
KASSERT(chain != NULL, ("ip_fw: no chain"));
|
||||
|
||||
/*
|
||||
* At this point, we're going to drop the packet.
|
||||
|
|
@ -1334,7 +1265,6 @@ got_match:
|
|||
* - The packet is not a multicast or broadcast packet
|
||||
*/
|
||||
if ((rule->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_REJECT
|
||||
&& ip
|
||||
&& (ip->ip_p != IPPROTO_ICMP || is_icmp_query(ip))
|
||||
&& !((*m)->m_flags & (M_BCAST|M_MCAST))
|
||||
&& !IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ static int ed_probe_pccard __P((struct isa_device *, u_char *));
|
|||
|
||||
static void ds_getmcaf __P((struct ed_softc *, u_long *));
|
||||
|
||||
static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int, int));
|
||||
static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int));
|
||||
|
||||
static __inline void ed_rint __P((struct ed_softc *));
|
||||
static __inline void ed_xmit __P((struct ed_softc *));
|
||||
|
|
@ -3063,7 +3063,7 @@ ed_rint(sc)
|
|||
* Go get packet.
|
||||
*/
|
||||
ed_get_packet(sc, packet_ptr + sizeof(struct ed_ring),
|
||||
len - sizeof(struct ed_ring), packet_hdr.rsr & ED_RSR_PHY);
|
||||
len - sizeof(struct ed_ring));
|
||||
ifp->if_ipackets++;
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -3475,14 +3475,13 @@ ed_ring_copy(sc, src, dst, amount)
|
|||
|
||||
/*
|
||||
* Retreive packet from shared memory and send to the next level up via
|
||||
* ether_input(). If there is a BPF listener, give a copy to BPF, too.
|
||||
* ether_input().
|
||||
*/
|
||||
static void
|
||||
ed_get_packet(sc, buf, len, multicast)
|
||||
ed_get_packet(sc, buf, len)
|
||||
struct ed_softc *sc;
|
||||
char *buf;
|
||||
u_short len;
|
||||
int multicast;
|
||||
{
|
||||
struct ether_header *eh;
|
||||
struct mbuf *m;
|
||||
|
|
@ -3520,63 +3519,25 @@ ed_get_packet(sc, buf, len, multicast)
|
|||
|
||||
#ifdef BRIDGE
|
||||
/*
|
||||
* Get link layer header, invoke brige_in, then
|
||||
* depending on the outcome of the test fetch the rest of the
|
||||
* packet and either pass up or call bdg_forward.
|
||||
* Don't read in the entire packet if we know we're going to drop it
|
||||
*/
|
||||
if (do_bridge) {
|
||||
struct ifnet *ifp ;
|
||||
int need_more = 1 ; /* in case not bpf */
|
||||
struct ifnet *bif;
|
||||
|
||||
if (sc->arpcom.ac_if.if_bpf) {
|
||||
need_more = 0 ;
|
||||
ed_ring_copy(sc, buf, (char *)eh, len);
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
} else
|
||||
ed_ring_copy(sc, buf, (char *)eh, 14);
|
||||
ifp = bridge_in(m);
|
||||
if (ifp == BDG_DROP) {
|
||||
ed_ring_copy(sc, buf, (char *)eh, ETHER_HDR_LEN);
|
||||
if ((bif = bridge_in(&sc->arpcom.ac_if, eh)) == BDG_DROP) {
|
||||
m_freem(m);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
/* else fetch rest of pkt and continue */
|
||||
if (need_more && len > 14)
|
||||
ed_ring_copy(sc, buf+14, (char *)(eh+1), len - 14);
|
||||
if (ifp != BDG_LOCAL )
|
||||
bdg_forward(&m, ifp); /* not local, need forwarding */
|
||||
if (ifp == BDG_LOCAL || ifp == BDG_BCAST || ifp == BDG_MCAST)
|
||||
goto getit ;
|
||||
/* not local and not multicast, just drop it */
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return ;
|
||||
}
|
||||
ed_ring_copy(sc, buf + ETHER_HDR_LEN,
|
||||
(char *)eh + ETHER_HDR_LEN, len - ETHER_HDR_LEN);
|
||||
} else
|
||||
#endif
|
||||
/*
|
||||
* Get packet, including link layer address, from interface.
|
||||
*/
|
||||
ed_ring_copy(sc, buf, (char *)eh, len);
|
||||
|
||||
/*
|
||||
* Check if there's a BPF listener on this interface. If so, hand off
|
||||
* the raw packet to bpf.
|
||||
*/
|
||||
if (sc->arpcom.ac_if.if_bpf)
|
||||
bpf_mtap(&sc->arpcom.ac_if, m);
|
||||
/*
|
||||
* If we are in promiscuous mode, we have to check whether
|
||||
* this packet is really for us.
|
||||
*/
|
||||
if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
|
||||
bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
sizeof(eh->ether_dhost)) != 0 && multicast == 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
/*
|
||||
* Remove link layer address.
|
||||
*/
|
||||
|
|
@ -3584,7 +3545,6 @@ getit:
|
|||
m->m_data += sizeof(struct ether_header);
|
||||
|
||||
ether_input(&sc->arpcom.ac_if, eh, m);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -122,11 +122,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -2133,47 +2128,12 @@ static void dc_rxeof(sc)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/* Handle BPF listeners. Let the BPF user see the packet */
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) && (bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
#endif
|
||||
|
||||
/* Don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
}
|
||||
|
||||
sc->dc_cdata.dc_rx_prod = i;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -89,11 +89,6 @@
|
|||
#include <pci/pcireg.h>
|
||||
#include <pci/dc21040reg.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Intel CPUs should use I/O mapped access.
|
||||
*/
|
||||
|
|
@ -3475,34 +3470,15 @@ tulip_rx_intr(
|
|||
#endif /* TULIP_BUS_DMA */
|
||||
|
||||
eh = *mtod(ms, struct ether_header *);
|
||||
#ifndef __FreeBSD__
|
||||
if (sc->tulip_if.if_bpf != NULL) {
|
||||
if (me == ms)
|
||||
bpf_tap(&sc->tulip_if, mtod(ms, caddr_t), total_len);
|
||||
else
|
||||
bpf_mtap(&sc->tulip_if, ms);
|
||||
}
|
||||
sc->tulip_flags |= TULIP_RXACT;
|
||||
|
||||
#ifdef BRIDGE /* see code in if_ed.c */
|
||||
ms->m_pkthdr.rcvif = ifp; /* XXX */
|
||||
ms->m_pkthdr.len = total_len; /* XXX */
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(ms);
|
||||
if (bdg_ifp == BDG_DROP)
|
||||
goto next ; /* and drop */
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&ms, bdg_ifp);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST &&
|
||||
bdg_ifp != BDG_MCAST)
|
||||
goto next ; /* and drop */
|
||||
/* all others accepted locally */
|
||||
} else
|
||||
#endif
|
||||
if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY))
|
||||
&& (eh.ether_dhost[0] & 1) == 0
|
||||
&& !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr))
|
||||
goto next;
|
||||
sc->tulip_flags |= TULIP_RXACT;
|
||||
accept = 1;
|
||||
} else {
|
||||
ifp->if_ierrors++;
|
||||
|
|
@ -3551,7 +3527,6 @@ tulip_rx_intr(
|
|||
#endif
|
||||
#endif /* TULIP_BUS_DMA */
|
||||
}
|
||||
next:
|
||||
#if defined(TULIP_DEBUG)
|
||||
cnt++;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -105,13 +105,6 @@
|
|||
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
|
||||
#endif /* __alpha__ */
|
||||
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/if_types.h>
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE! On the Alpha, we have an alignment constraint. The
|
||||
* card DMAs the packet immediately following the RFA. However,
|
||||
|
|
@ -1169,53 +1162,13 @@ rcvloop:
|
|||
goto rcvloop;
|
||||
}
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
total_len ;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
if (ifp->if_bpf)
|
||||
bpf_tap(FXP_BPFTAP_ARG(ifp),
|
||||
mtod(m, caddr_t),
|
||||
total_len);
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp == BDG_DROP)
|
||||
goto dropit ;
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (bdg_ifp != BDG_LOCAL &&
|
||||
bdg_ifp != BDG_BCAST &&
|
||||
bdg_ifp != BDG_MCAST)
|
||||
goto dropit ;
|
||||
goto getit ;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Only pass this packet up
|
||||
* if it is for us.
|
||||
*/
|
||||
if ((ifp->if_flags &
|
||||
IFF_PROMISC) &&
|
||||
(rfa->rfa_status &
|
||||
FXP_RFA_STATUS_IAMATCH) &&
|
||||
(eh->ether_dhost[0] & 1)
|
||||
== 0) {
|
||||
#ifdef BRIDGE
|
||||
dropit:
|
||||
#endif
|
||||
if (m)
|
||||
m_freem(m);
|
||||
goto rcvloop;
|
||||
}
|
||||
#ifdef BRIDGE
|
||||
getit:
|
||||
#endif
|
||||
m->m_data +=
|
||||
sizeof(struct ether_header);
|
||||
m->m_len -=
|
||||
sizeof(struct ether_header);
|
||||
m->m_pkthdr.len = m->m_len ;
|
||||
m->m_pkthdr.len = m->m_len;
|
||||
ether_input(ifp, eh, m);
|
||||
}
|
||||
goto rcvloop;
|
||||
|
|
|
|||
|
|
@ -1163,23 +1163,6 @@ static void rl_rxeof(sc)
|
|||
eh = mtod(m, struct ether_header *);
|
||||
ifp->if_ipackets++;
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -1019,20 +1019,9 @@ static void sf_rxeof(sc)
|
|||
eh = mtod(m, struct ether_header *);
|
||||
ifp->if_ipackets++;
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
||||
}
|
||||
|
||||
csr_write_4(sc, SF_CQ_CONSIDX,
|
||||
|
|
|
|||
|
|
@ -908,22 +908,6 @@ static void sis_rxeof(sc)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -1654,16 +1654,6 @@ static void sk_rxeof(sc_if)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc_if->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -48,11 +48,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -730,38 +725,6 @@ again:
|
|||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
|
||||
/* Handle BPF listeners. Let the BPF user see the packet. */
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) &&
|
||||
(bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Don't pass packet up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)){
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -1851,23 +1851,6 @@ static void ti_rxeof(sc)
|
|||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
|
||||
|
|
|
|||
|
|
@ -1549,26 +1549,6 @@ static int tl_intvec_rxeof(xsc, type)
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode. If we don't
|
||||
* want the packet, just forget it. We leave the mbuf in place
|
||||
* since it can be used again later.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
total_len - sizeof(struct ether_header);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
#include <sys/queue.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "opt_bdg.h"
|
||||
#define NBPFILTER 1
|
||||
|
||||
#include <net/if.h>
|
||||
|
|
@ -62,10 +61,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -932,51 +927,6 @@ epic_rx_done(sc)
|
|||
bpf_mtap( EPIC_BPFTAP_ARG(&sc->sc_if), m );
|
||||
#endif /* NBPFILTER > 0 */
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp == BDG_DROP) {
|
||||
if (m)
|
||||
m_free(m);
|
||||
continue; /* and drop */
|
||||
}
|
||||
if (bdg_ifp != BDG_LOCAL)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST &&
|
||||
bdg_ifp != BDG_MCAST) {
|
||||
if (m)
|
||||
m_free(m);
|
||||
continue; /* and drop */
|
||||
}
|
||||
/* all others accepted locally */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__FreeBSD__)
|
||||
/*
|
||||
* This deserves explanation
|
||||
* If the bridge is _on_, then the following check
|
||||
* must not be done because occasionally the bridge
|
||||
* gets packets that are local but have the ethernet
|
||||
* address of one of the other interfaces.
|
||||
*
|
||||
* But if the bridge is off, then we have to drop
|
||||
* stuff that came in just via bpf.
|
||||
*
|
||||
* In OpenBSD such filter stands in ether_input. (?)
|
||||
*/
|
||||
/* Accept only our packets, broadcasts and multicasts */
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge)
|
||||
#endif
|
||||
if ((eh->ether_dhost[0] & 1) == 0 &&
|
||||
bcmp(eh->ether_dhost,sc->sc_macaddr,ETHER_ADDR_LEN)){
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Second mbuf holds packet ifself */
|
||||
m->m_pkthdr.len = m->m_len = len - sizeof(struct ether_header);
|
||||
m->m_data += sizeof( struct ether_header );
|
||||
|
|
|
|||
|
|
@ -75,11 +75,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif /* BRIDGE */
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -1045,37 +1040,6 @@ static void vr_rxeof(sc)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) &&
|
||||
(bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* BRIDGE */
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
|
|
@ -102,10 +102,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -1203,43 +1199,10 @@ static void wb_rxeof(sc)
|
|||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) &&
|
||||
(bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) &&
|
||||
(eh->ether_dhost[0] & 1) == 0)) {
|
||||
m_freem(m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void wb_rxeoc(sc)
|
||||
|
|
|
|||
|
|
@ -1353,9 +1353,11 @@ wx_handle_rxint(sc)
|
|||
|
||||
for (idx = 0; idx < npkts; idx++) {
|
||||
mb = pending[idx];
|
||||
#ifndef __FreeBSD__
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(WX_BPFTAP_ARG(ifp), mb);
|
||||
}
|
||||
#endif
|
||||
ifp->if_ipackets++;
|
||||
if (sc->wx_debug) {
|
||||
printf("%s: RECV packet length %d\n",
|
||||
|
|
|
|||
|
|
@ -108,11 +108,6 @@
|
|||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include "opt_bdg.h"
|
||||
#ifdef BRIDGE
|
||||
#include <net/bridge.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
|
@ -1770,38 +1765,6 @@ again:
|
|||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
|
||||
/* Handle BPF listeners. Let the BPF user see the packet. */
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
#ifdef BRIDGE
|
||||
if (do_bridge) {
|
||||
struct ifnet *bdg_ifp ;
|
||||
bdg_ifp = bridge_in(m);
|
||||
if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_DROP)
|
||||
bdg_forward(&m, bdg_ifp);
|
||||
if (((bdg_ifp != BDG_LOCAL) && (bdg_ifp != BDG_BCAST) &&
|
||||
(bdg_ifp != BDG_MCAST)) || bdg_ifp == BDG_DROP) {
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Don't pass packet up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)){
|
||||
m_freem(m);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove header from mbuf and pass it on. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ether_input(ifp, eh, m);
|
||||
|
|
|
|||
Loading…
Reference in a new issue