I'll need this for some upcoming changes, at least to do it WITHOUT adding the 3rd or 4th or 5th copy of the bpf_mtap loop. most of these bpf_mtap_* are almost identical, minor differences in what to prepend, and foremost: passing custom copy functions. since bpf_mtap is all over the place I made bpf_mtap_hdr the flexible one: takes the copy function as parameter (if NULL, use default), and don't prepend anything if dlen == 0 (so can be used like bpf_mtap).
lightly tested. Index: arch/sparc/dev/if_ie.c =================================================================== RCS file: /cvs/src/sys/arch/sparc/dev/if_ie.c,v retrieving revision 1.45 diff -u -p -r1.45 if_ie.c --- arch/sparc/dev/if_ie.c 28 Nov 2013 22:18:52 -0000 1.45 +++ arch/sparc/dev/if_ie.c 8 Jul 2014 14:37:17 -0000 @@ -1335,7 +1335,7 @@ ie_readframe(sc, num) if (bpf_gets_it) { /* Pass it up. */ bpf_mtap_hdr(sc->sc_arpcom.ac_if.if_bpf, (caddr_t)&eh, - sizeof(eh), m, BPF_DIRECTION_IN); + sizeof(eh), m, BPF_DIRECTION_IN, NULL); } /* * A signal passed up from the filtering code indicating that the Index: net/bpf.c =================================================================== RCS file: /cvs/src/sys/net/bpf.c,v retrieving revision 1.93 diff -u -p -r1.93 bpf.c --- net/bpf.c 23 Apr 2014 10:50:18 -0000 1.93 +++ net/bpf.c 8 Jul 2014 15:09:10 -0000 @@ -92,6 +92,8 @@ LIST_HEAD(, bpf_d) bpf_d_list; void bpf_allocbufs(struct bpf_d *); void bpf_freed(struct bpf_d *); void bpf_ifname(struct ifnet *, struct ifreq *); +void _bpf_mtap(caddr_t, struct mbuf *, u_int, + void (*)(const void *, void *, size_t)); void bpf_mcopy(const void *, void *, size_t); int bpf_movein(struct uio *, u_int, struct mbuf **, struct sockaddr *, struct bpf_insn *); @@ -1159,10 +1161,11 @@ bpf_mcopy(const void *src_arg, void *dst } /* - * Incoming linkage from device drivers, when packet is in an mbuf chain. + * like bpf_mtap, but copy fn can be given. used by various bpf_mtap* */ void -bpf_mtap(caddr_t arg, struct mbuf *m, u_int direction) +_bpf_mtap(caddr_t arg, struct mbuf *m, u_int direction, + void (*cpfn)(const void *, void *, size_t)) { struct bpf_if *bp = (struct bpf_if *)arg; struct bpf_d *d; @@ -1174,6 +1177,9 @@ bpf_mtap(caddr_t arg, struct mbuf *m, u_ if (m == NULL) return; + if (cpfn == NULL) + cpfn = bpf_mcopy; + pktlen = 0; for (m0 = m; m0 != 0; m0 = m0->m_next) pktlen += m0->m_len; @@ -1191,13 +1197,22 @@ bpf_mtap(caddr_t arg, struct mbuf *m, u_ if (!gottime++) microtime(&tv); - bpf_catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy, &tv); + bpf_catchpacket(d, (u_char *)m, pktlen, slen, cpfn, &tv); if (d->bd_fildrop) m->m_flags |= M_FILDROP; } } /* + * Incoming linkage from device drivers, when packet is in an mbuf chain. + */ +void +bpf_mtap(caddr_t arg, struct mbuf *m, u_int direction) +{ + _bpf_mtap(arg, m, direction, NULL); +} + +/* * Incoming linkage from device drivers, where we have a mbuf chain * but need to prepend some arbitrary header from a linear buffer. * @@ -1208,17 +1223,23 @@ bpf_mtap(caddr_t arg, struct mbuf *m, u_ */ void bpf_mtap_hdr(caddr_t arg, caddr_t data, u_int dlen, struct mbuf *m, - u_int direction) + u_int direction, void (*cpfn)(const void *, void *, size_t)) { - struct m_hdr mh; - - mh.mh_flags = 0; - mh.mh_next = m; - mh.mh_len = dlen; - mh.mh_data = data; + struct m_hdr mh; + struct mbuf *m0; - bpf_mtap(arg, (struct mbuf *) &mh, direction); - m->m_flags |= mh.mh_flags & M_FILDROP; + if (dlen > 0) { + mh.mh_flags = 0; + mh.mh_next = m; + mh.mh_len = dlen; + mh.mh_data = data; + m0 = (struct mbuf *)&mh; + } else + m0 = m; + + _bpf_mtap(arg, (struct mbuf *) m0, direction, cpfn); + if (m0 != m) + m->m_flags |= m0->m_flags & M_FILDROP; } /* @@ -1233,17 +1254,10 @@ bpf_mtap_hdr(caddr_t arg, caddr_t data, void bpf_mtap_af(caddr_t arg, u_int32_t af, struct mbuf *m, u_int direction) { - struct m_hdr mh; u_int32_t afh; - mh.mh_flags = 0; - mh.mh_next = m; - mh.mh_len = 4; afh = htonl(af); - mh.mh_data = (caddr_t)&afh; - - bpf_mtap(arg, (struct mbuf *) &mh, direction); - m->m_flags |= mh.mh_flags & M_FILDROP; + bpf_mtap_hdr(arg, (caddr_t)&afh, 4, m, direction, NULL); } /* @@ -1259,7 +1273,6 @@ void bpf_mtap_ether(caddr_t arg, struct mbuf *m, u_int direction) { #if NVLAN > 0 - struct m_hdr mh; struct ether_vlan_header evh; if ((m->m_flags & M_VLANTAG) == 0) @@ -1277,13 +1290,7 @@ bpf_mtap_ether(caddr_t arg, struct mbuf m->m_len -= ETHER_HDR_LEN; m->m_data += ETHER_HDR_LEN; - mh.mh_flags = 0; - mh.mh_next = m; - mh.mh_len = sizeof(evh); - mh.mh_data = (caddr_t)&evh; - - bpf_mtap(arg, (struct mbuf *) &mh, direction); - m->m_flags |= mh.mh_flags & M_FILDROP; + bpf_mtap_hdr(arg, (caddr_t)&evh, sizeof(evh), m, direction, NULL); m->m_len += ETHER_HDR_LEN; m->m_data -= ETHER_HDR_LEN; @@ -1294,42 +1301,11 @@ 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; - struct timeval tv; - int gottime = 0; - 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; - - if (!gottime++) - microtime(&tv); - bpf_catchpacket(d, (u_char *)&mh, pktlen, slen, pflog_bpfcopy, - &tv); - } + bpf_mtap_hdr(arg, data, PFLOG_HDRLEN, m, BPF_DIRECTION_OUT, + pflog_bpfcopy); #endif } Index: net/bpf.h =================================================================== RCS file: /cvs/src/sys/net/bpf.h,v retrieving revision 1.43 diff -u -p -r1.43 bpf.h --- net/bpf.h 26 Mar 2012 19:37:42 -0000 1.43 +++ net/bpf.h 8 Jul 2014 14:40:33 -0000 @@ -272,7 +272,8 @@ struct bpf_dltlist { int bpf_validate(struct bpf_insn *, int); int bpf_tap(caddr_t, u_char *, u_int, u_int); void bpf_mtap(caddr_t, struct mbuf *, u_int); -void bpf_mtap_hdr(caddr_t, caddr_t, u_int, struct mbuf *, u_int); +void bpf_mtap_hdr(caddr_t, caddr_t, u_int, struct mbuf *, u_int, + void (*)(const void *, void *, size_t)); void bpf_mtap_af(caddr_t, u_int32_t, struct mbuf *, u_int); void bpf_mtap_ether(caddr_t, struct mbuf *, u_int); void bpf_mtap_pflog(caddr_t, caddr_t, struct mbuf *); Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v retrieving revision 1.223 diff -u -p -r1.223 if_bridge.c --- net/if_bridge.c 19 Apr 2014 14:39:26 -0000 1.223 +++ net/if_bridge.c 8 Jul 2014 14:30:30 -0000 @@ -1330,7 +1330,7 @@ bridge_input(struct ifnet *ifp, struct e #if NBPFILTER > 0 if (sc->sc_if.if_bpf) bpf_mtap_hdr(sc->sc_if.if_bpf, (caddr_t)eh, - ETHER_HDR_LEN, m, BPF_DIRECTION_IN); + ETHER_HDR_LEN, m, BPF_DIRECTION_IN, NULL); #endif bridge_span(sc, eh, m); @@ -1441,10 +1441,8 @@ bridge_input(struct ifnet *ifp, struct e * is aware */ #if NBPFILTER > 0 if (ifl->ifp->if_bpf) - bpf_mtap_hdr(ifl->ifp->if_bpf, - (caddr_t)eh, - ETHER_HDR_LEN, m, - BPF_DIRECTION_IN); + bpf_mtap_hdr(ifl->ifp->if_bpf, (caddr_t)eh, + ETHER_HDR_LEN, m, BPF_DIRECTION_IN, NULL); #endif /* Count for the interface we are going to */ ifl->ifp->if_ipackets++; Index: net/if_trunk.c =================================================================== RCS file: /cvs/src/sys/net/if_trunk.c,v retrieving revision 1.87 diff -u -p -r1.87 if_trunk.c --- net/if_trunk.c 10 Mar 2014 12:21:35 -0000 1.87 +++ net/if_trunk.c 8 Jul 2014 14:31:04 -0000 @@ -1102,7 +1102,7 @@ trunk_input(struct ifnet *ifp, struct et #if NBPFILTER > 0 if (trifp->if_bpf && tr->tr_proto != TRUNK_PROTO_FAILOVER) bpf_mtap_hdr(trifp->if_bpf, (char *)eh, ETHER_HDR_LEN, m, - BPF_DIRECTION_IN); + BPF_DIRECTION_IN, NULL); #endif error = (*tr->tr_input)(tr, tp, eh, m); @@ -1372,7 +1372,7 @@ trunk_fail_input(struct trunk_softc *tr, #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap_hdr(ifp->if_bpf, (char *)eh, ETHER_HDR_LEN, m, - BPF_DIRECTION_IN); + BPF_DIRECTION_IN, NULL); #endif m->m_pkthdr.rcvif = ifp; Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.105 diff -u -p -r1.105 if_vlan.c --- net/if_vlan.c 14 May 2014 21:48:50 -0000 1.105 +++ net/if_vlan.c 8 Jul 2014 14:31:47 -0000 @@ -299,7 +299,7 @@ vlan_input(struct ether_header *eh, stru #if NBPFILTER > 0 if (ifv->ifv_if.if_bpf) bpf_mtap_hdr(ifv->ifv_if.if_bpf, (char *)eh, ETHER_HDR_LEN, m, - BPF_DIRECTION_IN); + BPF_DIRECTION_IN, NULL); #endif /* Index: netinet/ip_ah.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ah.c,v retrieving revision 1.108 diff -u -p -r1.108 ip_ah.c --- netinet/ip_ah.c 9 Jan 2014 06:29:05 -0000 1.108 +++ netinet/ip_ah.c 8 Jul 2014 14:39:01 -0000 @@ -1016,7 +1016,7 @@ ah_output(struct mbuf *m, struct tdb *td hdr.flags |= M_AUTH; bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, - ENC_HDRLEN, m, BPF_DIRECTION_OUT); + ENC_HDRLEN, m, BPF_DIRECTION_OUT, NULL); } } #endif Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.230 diff -u -p -r1.230 ip_carp.c --- netinet/ip_carp.c 30 Jun 2014 07:02:22 -0000 1.230 +++ netinet/ip_carp.c 8 Jul 2014 14:39:01 -0000 @@ -1454,7 +1454,7 @@ carp_input(struct ifnet *ifp0, struct et #if NBPFILTER > 0 if (vh->sc_if.if_bpf) bpf_mtap_hdr(vh->sc_if.if_bpf, (char *)&eh, - ETHER_HDR_LEN, m0, BPF_DIRECTION_IN); + ETHER_HDR_LEN, m0, BPF_DIRECTION_IN, NULL); #endif vh->sc_if.if_ipackets++; ether_input(&vh->sc_if, &eh, m0); @@ -1470,7 +1470,7 @@ carp_input(struct ifnet *ifp0, struct et #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap_hdr(ifp->if_bpf, (char *)&eh, ETHER_HDR_LEN, m, - BPF_DIRECTION_IN); + BPF_DIRECTION_IN, NULL); #endif ifp->if_ipackets++; ether_input(ifp, &eh, m); Index: netinet/ip_esp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_esp.c,v retrieving revision 1.123 diff -u -p -r1.123 ip_esp.c --- netinet/ip_esp.c 9 Jan 2014 06:29:06 -0000 1.123 +++ netinet/ip_esp.c 8 Jul 2014 14:39:01 -0000 @@ -803,7 +803,7 @@ esp_output(struct mbuf *m, struct tdb *t hdr.flags |= M_AUTH; bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, - ENC_HDRLEN, m, BPF_DIRECTION_OUT); + ENC_HDRLEN, m, BPF_DIRECTION_OUT, NULL); } } #endif Index: netinet/ip_ipcomp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ipcomp.c,v retrieving revision 1.33 diff -u -p -r1.33 ip_ipcomp.c --- netinet/ip_ipcomp.c 9 Jan 2014 06:29:06 -0000 1.33 +++ netinet/ip_ipcomp.c 8 Jul 2014 14:39:01 -0000 @@ -402,7 +402,7 @@ ipcomp_output(m, tdb, mp, skip, protoff) hdr.spi = tdb->tdb_spi; bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, - ENC_HDRLEN, m, BPF_DIRECTION_OUT); + ENC_HDRLEN, m, BPF_DIRECTION_OUT, NULL); } } #endif Index: netinet/ipsec_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ipsec_input.c,v retrieving revision 1.120 diff -u -p -r1.120 ipsec_input.c --- netinet/ipsec_input.c 14 Apr 2014 09:06:42 -0000 1.120 +++ netinet/ipsec_input.c 8 Jul 2014 14:39:01 -0000 @@ -702,7 +702,7 @@ ipsec_common_input_cb(struct mbuf *m, st hdr.flags = m->m_flags & (M_AUTH|M_CONF); bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, - ENC_HDRLEN, m, BPF_DIRECTION_IN); + ENC_HDRLEN, m, BPF_DIRECTION_IN, NULL); } } #endif