Date: Tue, 26 Nov 2002 22:54:02 +0200 From: Mihail Balikov <misho@interbgc.com> To: Fabien THOMAS <fabien.thomas@netasq.com> Cc: freebsd-net@freebsd.org Subject: Re: bpf_tap problem with PKTHDR Message-ID: <20021126205402.63098.qmail@ns1.interbgc.com> In-Reply-To: <127338536921.20021126141359@netasq.com> References: <127338536921.20021126141359@netasq.com>
next in thread | previous in thread | raw e-mail | index | archive | help
I found similar problem with bpf flag BIOCSSEESENT. Here is simple
workaround:
if_ethersubr.c: ether_input()
/* Check for a BPF tap */
if (ifp->if_bpf != NULL) {
/* This kludge is OK; BPF treats the "mbuf" as read-only */
struct mbuf m0;
m0.m_next = m;
m0.m_data = (char *)eh;
m0.m_len = ETHER_HDR_LEN;
/* make BOICSSEESENT happy */
m0.m_pkthdr.rcvif = ifp;
bpf_mtap(ifp, &m0);
}
But there's no reason for such "kludge", if ethernet header is first mbuf.
regards,
Mihail
Fabien THOMAS writes:
> Hi,
>
> It seems there is a problem in the bpf_mtap code:
>
> Actually the code assume in the seesent case that mbuf will have a pkthdr structure.
>
> There is 2 problems here:
> + they did not check for that with (m_flag & M_PKTHDR)
> + at the upper level the caller forge fake mbuf that did not
> contain any pkthdr and did not initialize the m_flags field
>
> what do you think about that ?
>
> if_ethersubr.c case:
>
> /* 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);
> }
>
>
> bpf_mtap function:
> /*
> * Incoming linkage from device drivers, when packet is in an mbuf chain.
> */
> void
> bpf_mtap(ifp, m)
> struct ifnet *ifp;
> struct mbuf *m;
> {
> struct bpf_if *bp = ifp->if_bpf;
> struct bpf_d *d;
> u_int pktlen, slen;
> struct mbuf *m0;
>
> pktlen = 0;
> for (m0 = m; m0 != 0; m0 = m0->m_next)
> pktlen += m0->m_len;
>
> for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
> if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
> continue;
> ++d->bd_rcount;
> slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
> if (slen != 0)
> catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
> }
> }
>
> fabien
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021126205402.63098.qmail>
