summaryrefslogtreecommitdiffstats
path: root/sys/net/bpf.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2007-09-10 00:03:06 +0000
committerthompsa <thompsa@FreeBSD.org>2007-09-10 00:03:06 +0000
commit16614f83a02ff04ff50789782e884d690ccbb78b (patch)
tree7237d6d46cdd2b98f5813f2433440d705d7f31c8 /sys/net/bpf.c
parent198c38400acd01acb916e7350ad6b0a60e56068e (diff)
downloadFreeBSD-src-16614f83a02ff04ff50789782e884d690ccbb78b.zip
FreeBSD-src-16614f83a02ff04ff50789782e884d690ccbb78b.tar.gz
Check for multicast destination on bpf injected packets and update the M_*CAST
flags, the absense of these flags causes problems in other areas such as bridging which expect them to be correct. At the moment only Ethernet DLTs are checked. Reviewed by: bms, csjp, sam Approved by: re (bmah)
Diffstat (limited to 'sys/net/bpf.c')
-rw-r--r--sys/net/bpf.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 5d6dc02..05682ff 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -102,7 +102,7 @@ static void bpf_attachd(struct bpf_d *, struct bpf_if *);
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, int mtu, struct mbuf **mp,
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, int mtu, struct mbuf **mp,
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 *uio, int ioflag)
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);
OpenPOWER on IntegriCloud