Subject: Re: adding an 802.11 data link type
To: None <wrstuden@netbsd.org>
From: Atsushi Onoe <onoe@sm.sony.co.jp>
List: tech-net
Date: 08/06/2002 09:44:59
<Pine.NEB.4.33.0208051442050.16377-100000@vespasia.home-net.internetconnect.net>
References:
<Pine.NEB.4.33.0208051442050.16377-100000@vespasia.home-net.internetconnect.net>
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
> > > 1) A driver supporting more than one DLT will call bpf with a new
> > > procedure, bpfattach_multidlt, passing bpfattach_multidlt a mask
> > > describing the DLTs the driver supports.
> >
> > Since the number of supported DLTs for a driver would be limited,
> > multiple calls to bpfattach_dlt() may be accepted.
> > This would help to implement streight forward implementation which splits
> > bpf_if for each DLT.
>
> But do we want multiple bpf_if's? My original idea was there would be one
> bpf, just it could hand back different packet types.
Hmm, I've found my previous implementation. I admit it is something like
ad hoc, but it works well and it has complete compatibility.
Atsushi Onoe
(not complete patch)
Index: net/bpf.c
===================================================================
RCS file: /cvsroot/syssrc/sys/net/bpf.c,v
retrieving revision 1.65
diff -u -r1.65 bpf.c
--- net/bpf.c 2002/06/06 23:54:47 1.65
+++ net/bpf.c 2002/08/05 07:02:30
@@ -746,6 +746,32 @@
break;
/*
+ * Set device parameters.
+ */
+ case BIOCSDLT:
+ if (d->bd_bif == 0)
+ error = EINVAL;
+ else if (d->bd_bif->bif_dlt != *(u_int *)addr) {
+ struct bpf_if *bp;
+
+ for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
+ if (bp->bif_ifp == d->bd_bif->bif_ifp &&
+ bp->bif_dlt == *(u_int *)addr)
+ break;
+ }
+ if (bp == 0)
+ error = EINVAL;
+ else {
+ s = splnet();
+ bpf_detachd(d);
+ bpf_attachd(d, bp);
+ reset_d(d);
+ splx(s);
+ }
+ }
+ break;
+
+ /*
* Set interface name.
*/
case BIOCGETIF:
@@ -946,6 +972,9 @@
if (ifp == 0 ||
strcmp(ifp->if_xname, ifr->ifr_name) != 0)
continue;
+ /* skip additional entry */
+ if (bp->bif_driverp != (struct bpf_if **)&ifp->if_bpf)
+ continue;
/*
* We found the requested interface.
* If it's not up, return an error.
@@ -1227,13 +1256,28 @@
struct ifnet *ifp;
u_int dlt, hdrlen;
{
+
+ bpfattach2(ifp, dlt, hdrlen, &ifp->if_bpf);
+}
+
+/*
+ * Attach additional dlt for a interface to bpf. dlt is the link layer type;
+ * hdrlen is the fixed size of the link header for the specified dlt
+ * (variable length headers not yet supported).
+ */
+void
+bpfattach2(ifp, dlt, hdrlen, driverp)
+ struct ifnet *ifp;
+ u_int dlt, hdrlen;
+ caddr_t *driverp;
+{
struct bpf_if *bp;
bp = (struct bpf_if *)malloc(sizeof(*bp), M_DEVBUF, M_DONTWAIT);
if (bp == 0)
panic("bpfattach");
bp->bif_dlist = 0;
- bp->bif_driverp = (struct bpf_if **)&ifp->if_bpf;
+ bp->bif_driverp = (struct bpf_if **)driverp;
bp->bif_ifp = ifp;
bp->bif_dlt = dlt;
@@ -1288,12 +1332,13 @@
}
}
+ again:
for (bp = bpf_iflist, pbp = &bpf_iflist;
bp != NULL; pbp = &bp->bif_next, bp = bp->bif_next) {
if (bp->bif_ifp == ifp) {
*pbp = bp->bif_next;
free(bp, M_DEVBUF);
- break;
+ goto again;
}
}
}
Index: net/if_ieee80211.h
===================================================================
RCS file: /cvsroot/syssrc/sys/net/if_ieee80211.h,v
retrieving revision 1.13
diff -u -r1.13 if_ieee80211.h
--- net/if_ieee80211.h 2002/08/05 06:55:05 1.13
+++ net/if_ieee80211.h 2002/08/05 07:29:50
@@ -308,6 +308,7 @@
struct ifqueue ic_mgtq;
int ic_flags;
enum ieee80211_state ic_state;
+ caddr_t ic_rawbpf; /* packet filter structure */
struct ieee80211_bss ic_bss; /* information for this node */
int ic_bss_privlen; /* size for bs_private */
u_int8_t ic_ibss_chan;
Index: net/if_ieee80211subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/net/if_ieee80211subr.c,v
retrieving revision 1.8
diff -u -r1.8 if_ieee80211subr.c
--- net/if_ieee80211subr.c 2002/08/05 06:55:06 1.8
+++ net/if_ieee80211subr.c 2002/08/05 07:04:53
@@ -129,6 +129,10 @@
int i, rate;
ether_ifattach(ifp, ic->ic_myaddr);
+#if NBPFILTER > 0
+ bpfattach2(ifp, DLT_IEEE802_11,
+ sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);
+#endif
ieee80211_crc_init();
memcpy(ic->ic_chan_active, ic->ic_chan_avail,
sizeof(ic->ic_chan_active));
@@ -236,6 +240,11 @@
goto err;
wh = mtod(m, struct ieee80211_frame *);
}
+#if NBPFILTER > 0
+ /* copy to listener after decrypt */
+ if (ic->ic_rawbpf)
+ bpf_mtap(ic->ic_rawbpf, m);
+#endif
dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
Index: dev/ic/awi.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/awi.c,v
retrieving revision 1.43
diff -u -r1.43 awi.c
--- dev/ic/awi.c 2002/08/05 06:55:07 1.43
+++ dev/ic/awi.c 2002/08/05 07:16:59
@@ -653,6 +653,10 @@
continue;
}
}
+#if NBPFILTER > 0
+ if (ic->ic_rawbpf)
+ bpf_mtap(ic->ic_rawbpf, m0);
+#endif
if (dowep) {
if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL) {
ifp->if_oerrors++;