o add support for multiple link types per interface (e.g. 802.11 and Ethernet)
o introduce BPF_TAP and BPF_MTAP macros to hide implementation details and ease code portability o use m_getcl where appropriate Reviewed by: many Approved by: re Obtained from: NetBSD (multiple link type support)
This commit is contained in:
parent
e1796d40b9
commit
24a229f466
@ -204,19 +204,17 @@ bpf_movein(uio, linktype, mp, sockp, datlen)
|
||||
if ((unsigned)len > MCLBYTES)
|
||||
return (EIO);
|
||||
|
||||
MGETHDR(m, M_TRYWAIT, MT_DATA);
|
||||
if (m == 0)
|
||||
return (ENOBUFS);
|
||||
if (len > MHLEN) {
|
||||
MCLGET(m, M_TRYWAIT);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR);
|
||||
} else {
|
||||
MGETHDR(m, M_TRYWAIT, MT_DATA);
|
||||
}
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
*mp = m;
|
||||
|
||||
/*
|
||||
* Make room for link header.
|
||||
*/
|
||||
@ -235,7 +233,7 @@ bpf_movein(uio, linktype, mp, sockp, datlen)
|
||||
error = uiomove(mtod(m, caddr_t), len - hlen, uio);
|
||||
if (!error)
|
||||
return (0);
|
||||
bad:
|
||||
bad:
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
@ -258,7 +256,7 @@ bpf_attachd(d, bp)
|
||||
d->bd_next = bp->bif_dlist;
|
||||
bp->bif_dlist = d;
|
||||
|
||||
bp->bif_ifp->if_bpf = bp;
|
||||
*bp->bif_driverp = bp;
|
||||
BPFIF_UNLOCK(bp);
|
||||
}
|
||||
|
||||
@ -304,7 +302,7 @@ bpf_detachd(d)
|
||||
/*
|
||||
* Let the driver know that there are no more listeners.
|
||||
*/
|
||||
d->bd_bif->bif_ifp->if_bpf = 0;
|
||||
*d->bd_bif->bif_driverp = 0;
|
||||
BPFIF_UNLOCK(bp);
|
||||
d->bd_bif = 0;
|
||||
}
|
||||
@ -969,6 +967,9 @@ bpf_setif(d, ifr)
|
||||
|
||||
if (ifp == 0 || ifp != theywant)
|
||||
continue;
|
||||
/* skip additional entry */
|
||||
if (bp->bif_driverp != (struct bpf_if **)&ifp->if_bpf)
|
||||
continue;
|
||||
|
||||
mtx_unlock(&bpf_mtx);
|
||||
/*
|
||||
@ -1058,16 +1059,14 @@ bpfpoll(dev, events, td)
|
||||
* buffer.
|
||||
*/
|
||||
void
|
||||
bpf_tap(ifp, pkt, pktlen)
|
||||
struct ifnet *ifp;
|
||||
bpf_tap(bp, pkt, pktlen)
|
||||
struct bpf_if *bp;
|
||||
register u_char *pkt;
|
||||
register u_int pktlen;
|
||||
{
|
||||
struct bpf_if *bp;
|
||||
register struct bpf_d *d;
|
||||
register u_int slen;
|
||||
|
||||
bp = ifp->if_bpf;
|
||||
BPFIF_LOCK(bp);
|
||||
for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
|
||||
BPFD_LOCK(d);
|
||||
@ -1075,7 +1074,7 @@ bpf_tap(ifp, pkt, pktlen)
|
||||
slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
|
||||
if (slen != 0) {
|
||||
#ifdef MAC
|
||||
if (mac_check_bpfdesc_receive(d, ifp) == 0)
|
||||
if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
|
||||
#endif
|
||||
catchpacket(d, pkt, pktlen, slen, bcopy);
|
||||
}
|
||||
@ -1115,17 +1114,16 @@ bpf_mcopy(src_arg, dst_arg, len)
|
||||
* Incoming linkage from device drivers, when packet is in an mbuf chain.
|
||||
*/
|
||||
void
|
||||
bpf_mtap(ifp, m)
|
||||
struct ifnet *ifp;
|
||||
bpf_mtap(bp, m)
|
||||
struct bpf_if *bp;
|
||||
struct mbuf *m;
|
||||
{
|
||||
struct bpf_if *bp = ifp->if_bpf;
|
||||
struct bpf_d *d;
|
||||
u_int pktlen, slen;
|
||||
|
||||
pktlen = m_length(m, NULL);
|
||||
if (pktlen == m->m_len) {
|
||||
bpf_tap(ifp, mtod(m, u_char *), pktlen);
|
||||
bpf_tap(bp, mtod(m, u_char *), pktlen);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1138,7 +1136,7 @@ bpf_mtap(ifp, m)
|
||||
slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
|
||||
if (slen != 0)
|
||||
#ifdef MAC
|
||||
if (mac_check_bpfdesc_receive(d, ifp) == 0)
|
||||
if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0)
|
||||
#endif
|
||||
catchpacket(d, (u_char *)m, pktlen, slen,
|
||||
bpf_mcopy);
|
||||
@ -1266,21 +1264,37 @@ bpf_freed(d)
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach an interface to bpf. ifp is a pointer to the structure
|
||||
* defining the interface to be attached, dlt is the link layer type,
|
||||
* and hdrlen is the fixed size of the link header (variable length
|
||||
* headers are not yet supporrted).
|
||||
* Attach an interface to bpf. dlt is the link layer type; hdrlen is the
|
||||
* fixed size of the link header (variable length headers not yet supported).
|
||||
*/
|
||||
void
|
||||
bpfattach(ifp, dlt, hdrlen)
|
||||
struct ifnet *ifp;
|
||||
u_int dlt, hdrlen;
|
||||
{
|
||||
|
||||
bpfattach2(ifp, dlt, hdrlen, &ifp->if_bpf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach an interface to bpf. ifp is a pointer to the structure
|
||||
* defining the interface to be attached, dlt is the link layer type,
|
||||
* and hdrlen is the fixed size of the link header (variable length
|
||||
* headers are not yet supporrted).
|
||||
*/
|
||||
void
|
||||
bpfattach2(ifp, dlt, hdrlen, driverp)
|
||||
struct ifnet *ifp;
|
||||
u_int dlt, hdrlen;
|
||||
struct bpf_if **driverp;
|
||||
{
|
||||
struct bpf_if *bp;
|
||||
bp = (struct bpf_if *)malloc(sizeof(*bp), M_BPF, M_NOWAIT | M_ZERO);
|
||||
if (bp == 0)
|
||||
panic("bpfattach");
|
||||
|
||||
bp->bif_dlist = 0;
|
||||
bp->bif_driverp = driverp;
|
||||
bp->bif_ifp = ifp;
|
||||
bp->bif_dlt = dlt;
|
||||
mtx_init(&bp->bif_mtx, "bpf interface lock", NULL, MTX_DEF);
|
||||
@ -1290,7 +1304,7 @@ bpfattach(ifp, dlt, hdrlen)
|
||||
bpf_iflist = bp;
|
||||
mtx_unlock(&bpf_mtx);
|
||||
|
||||
bp->bif_ifp->if_bpf = 0;
|
||||
*bp->bif_driverp = 0;
|
||||
|
||||
/*
|
||||
* Compute the length of the bpf header. This is not necessarily
|
||||
@ -1301,7 +1315,7 @@ bpfattach(ifp, dlt, hdrlen)
|
||||
bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
|
||||
|
||||
if (bootverbose)
|
||||
printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
|
||||
if_printf(ifp, "bpf attached\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -340,14 +340,25 @@ struct bpf_insn {
|
||||
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct bpf_if;
|
||||
int bpf_validate(const struct bpf_insn *, int);
|
||||
void bpf_tap(struct ifnet *, u_char *, u_int);
|
||||
void bpf_mtap(struct ifnet *, struct mbuf *);
|
||||
void bpf_tap(struct bpf_if *, u_char *, u_int);
|
||||
void bpf_mtap(struct bpf_if *, struct mbuf *);
|
||||
void bpfattach(struct ifnet *, u_int, u_int);
|
||||
void bpfattach2(struct ifnet *, u_int, u_int, struct bpf_if **);
|
||||
void bpfdetach(struct ifnet *);
|
||||
|
||||
void bpfilterattach(int);
|
||||
u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int);
|
||||
|
||||
#define BPF_TAP(_ifp,_pkt,_pktlen) do { \
|
||||
if ((_ifp)->if_bpf) \
|
||||
bpf_tap((_ifp)->if_bpf, (_pkt), (_pktlen)); \
|
||||
} while (0)
|
||||
#define BPF_MTAP(_ifp,_m) do { \
|
||||
if ((_ifp)->if_bpf) \
|
||||
bpf_mtap((_ifp)->if_bpf, (_m)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -355,4 +366,4 @@ u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int);
|
||||
*/
|
||||
#define BPF_MEMWORDS 16
|
||||
|
||||
#endif
|
||||
#endif /* _NET_BPF_H_ */
|
||||
|
@ -110,6 +110,7 @@ struct bpf_d {
|
||||
struct bpf_if {
|
||||
struct bpf_if *bif_next; /* list of all interfaces */
|
||||
struct bpf_d *bif_dlist; /* descriptor list */
|
||||
struct bpf_if **bif_driverp; /* pointer into softc */
|
||||
u_int bif_dlt; /* link layer type */
|
||||
u_int bif_hdrlen; /* length of header (with padding) */
|
||||
struct ifnet *bif_ifp; /* corresponding interface */
|
||||
|
Loading…
Reference in New Issue
Block a user