/* * Incoming linkage from device drivers. Process the packet pkt, of length * pktlen, which is stored in a contiguous buffer. The packet is parsed * by each process' filter, and if accepted, stashed into the corresponding * buffer. */ int bpf_tap(caddr_t arg, u_char *pkt, u_int pktlen, u_int direction) { struct bpf_if *bp; struct bpf_d *d; size_t slen; int drop = 0; /* * Note that the ipl does not have to be raised at this point. * The only problem that could arise here is that if two different * interfaces shared any data. This is not the case. */ bp = (struct bpf_if *)arg; for (d = bp->bif_dlist; d != 0; d = d->bd_next) { ++d->bd_rcount; if ((direction & d->bd_dirfilt) != 0) slen = 0; else slen = bpf_filter(d->bd_rfilter, pkt, pktlen, pktlen); if (slen != 0) { bpf_catchpacket(d, pkt, pktlen, slen, bcopy); if (d->bd_fildrop) drop++; } } return (drop); }
/* * Incoming linkage from device drivers, when packet is in an mbuf chain. */ void bpf_mtap(caddr_t arg, struct mbuf *m, u_int direction) { struct bpf_if *bp = (struct bpf_if *)arg; struct bpf_d *d; size_t pktlen, slen; struct mbuf *m0; if (m == NULL) return; 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) { ++d->bd_rcount; if ((direction & d->bd_dirfilt) != 0) slen = 0; else slen = bpf_filter(d->bd_rfilter, (u_char *)m, pktlen, 0); if (slen == 0) continue; bpf_catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); if (d->bd_fildrop) m->m_flags |= M_FILDROP; } }
void bpf_mtap_pflog(caddr_t arg, caddr_t data, struct mbuf *m) { #if NPFLOG > 0 struct m_hdr mh; struct bpf_if *bp = (struct bpf_if *)arg; struct bpf_d *d; size_t pktlen, slen; struct mbuf *m0; if (m == NULL) return; mh.mh_flags = 0; mh.mh_next = m; mh.mh_len = PFLOG_HDRLEN; mh.mh_data = data; pktlen = mh.mh_len; for (m0 = m; m0 != 0; m0 = m0->m_next) pktlen += m0->m_len; for (d = bp->bif_dlist; d != 0; d = d->bd_next) { ++d->bd_rcount; if ((BPF_DIRECTION_OUT & d->bd_dirfilt) != 0) slen = 0; else slen = bpf_filter(d->bd_rfilter, (u_char *)&mh, pktlen, 0); if (slen == 0) continue; bpf_catchpacket(d, (u_char *)&mh, pktlen, slen, pflog_bpfcopy); } #endif }