multicast packets from bpf
Andrew Thompson
thompsa at FreeBSD.org
Tue Aug 28 14:29:27 PDT 2007
On Tue, Aug 28, 2007 at 09:22:10PM +0100, Bruce M. Simpson wrote:
> Andrew Thompson wrote:
> >I had originally started to put it there but realised that I need a
> >pointer to the ifnet to read if_broadcastaddr, I didnt think it was
> >worth changing the function parameters when the check can also just go
> >in bpfwrite. I dont mind moving it if its the more correct place to put
> >it.
> >
>
> It's already got a switch..case breakout for the DLTs and knows how to
> grok the 802.11 header format which can have up to 6 (yes, 6) 802.3
> style MAC addresses, all of which mean different things depending on
> whether you are STA, AP, Mesh Portal, Mesh AP... :-)
>
> So it seems like the right place. bpf_movein() is static and referenced
> once within its translation unit, so it is a candidate for inlining; I
> would change ifp-?if_mtu to ifp in the call.
The patch has been updated (attached).
> >Is the tapwrite patch still needed? The mbuf is passed to ether_input
> >which should do the right thing.
> >
>
> Good point. A casual reading suggests it *may* no longer be needed since
> my pass over ether_input(), but seeing as we're due to branch and all,
> I'll leave garbage collecting the 10 lines in tapwrite() to someone
> else. :-)
I would leave it there for the moment.
Andrew
-------------- next part --------------
Index: bpf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bpf.c,v
retrieving revision 1.180
diff -u -p -r1.180 bpf.c
--- bpf.c 6 Aug 2007 14:26:00 -0000 1.180
+++ bpf.c 28 Aug 2007 21:22:59 -0000
@@ -102,7 +102,7 @@ static void bpf_attachd(struct bpf_d *,
static void bpf_detachd(struct bpf_d *);
static void bpf_freed(struct bpf_d *);
static void bpf_mcopy(const void *, void *, size_t);
-static int bpf_movein(struct uio *, int, int, struct mbuf **,
+static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **,
struct sockaddr *, int *, struct bpf_insn *);
static int bpf_setif(struct bpf_d *, struct ifreq *);
static void bpf_timed_out(void *);
@@ -158,10 +158,11 @@ static struct filterops bpfread_filtops
{ 1, NULL, filt_bpfdetach, filt_bpfread };
static int
-bpf_movein(struct uio *uio, int linktype, int mtu, struct mbuf **mp,
+bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
struct sockaddr *sockp, int *hdrlen, struct bpf_insn *wfilter)
{
const struct ieee80211_bpf_params *p;
+ struct ether_header *eh;
struct mbuf *m;
int error;
int len;
@@ -241,7 +242,7 @@ bpf_movein(struct uio *uio, int linktype
len = uio->uio_resid;
- if (len - hlen > mtu)
+ if (len - hlen > ifp->if_mtu)
return (EMSGSIZE);
if ((unsigned)len > MCLBYTES)
@@ -273,6 +274,20 @@ bpf_movein(struct uio *uio, int linktype
goto bad;
}
+ /* Check for multicast destination */
+ switch (linktype) {
+ case DLT_EN10MB:
+ eh = mtod(m, struct ether_header *);
+ if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ if (bcmp(ifp->if_broadcastaddr, eh->ether_dhost,
+ ETHER_ADDR_LEN) == 0)
+ m->m_flags |= M_BCAST;
+ else
+ m->m_flags |= M_MCAST;
+ }
+ break;
+ }
+
/*
* Make room for link header, and copy it to sockaddr
*/
@@ -615,7 +630,7 @@ bpfwrite(struct cdev *dev, struct uio *u
bzero(&dst, sizeof(dst));
m = NULL;
hlen = 0;
- error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp->if_mtu,
+ error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp,
&m, &dst, &hlen, d->bd_wfilter);
if (error)
return (error);
More information about the freebsd-current
mailing list