add bpf_tap_hdr(), for handling a buffer (not an mbuf) with a header.
authordlg <dlg@openbsd.org>
Thu, 1 Feb 2018 12:10:27 +0000 (12:10 +0000)
committerdlg <dlg@openbsd.org>
Thu, 1 Feb 2018 12:10:27 +0000 (12:10 +0000)
internally it uses mbufs to handle the chain of buffers, but the
caller doesnt have to deal with that or allocate a temporary buffer
with the header attached.

ok mpi@

sys/net/bpf.c
sys/net/bpf.h

index 2d37951..af7406e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.c,v 1.166 2018/01/24 00:25:17 dlg Exp $   */
+/*     $OpenBSD: bpf.c,v 1.167 2018/02/01 12:10:27 dlg Exp $   */
 /*     $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
 
 /*
@@ -1290,6 +1290,45 @@ _bpf_mtap(caddr_t arg, const struct mbuf *m, u_int direction,
        return (drop);
 }
 
+/*
+ * Incoming linkage from device drivers, where a data buffer should be
+ * prepended by an arbitrary header. In this situation we already have a
+ * way of representing a chain of memory buffers, ie, mbufs, so reuse
+ * the existing functionality by attaching the buffers to mbufs.
+ *
+ * Con up a minimal mbuf chain to pacify bpf by allocating (only) a
+ * struct m_hdr each for the header and data on the stack.
+ */
+int
+bpf_tap_hdr(caddr_t arg, const void *hdr, unsigned int hdrlen,
+    const void *buf, unsigned int buflen, u_int direction)
+{
+       struct m_hdr mh, md;
+       struct mbuf *m0 = NULL;
+       struct mbuf **mp = &m0;
+
+       if (hdr != NULL) {
+               mh.mh_flags = 0;
+               mh.mh_next = NULL;
+               mh.mh_len = hdrlen;
+               mh.mh_data = (void *)hdr;
+
+               *mp = (struct mbuf *)&mh;
+               mp = &mh.mh_next;
+       }
+
+       if (buf != NULL) {
+               md.mh_flags = 0;
+               md.mh_next = NULL;
+               md.mh_len = buflen;
+               md.mh_data = (void *)buf;
+
+               *mp = (struct mbuf *)&md;
+       }
+
+       return _bpf_mtap(arg, m0, direction, bpf_mcopy);
+}
+
 /*
  * Incoming linkage from device drivers, when packet is in an mbuf chain.
  */
index 98afe4f..cb713ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.h,v 1.63 2018/01/24 00:25:17 dlg Exp $    */
+/*     $OpenBSD: bpf.h,v 1.64 2018/02/01 12:10:27 dlg Exp $    */
 /*     $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $   */
 
 /*
@@ -311,6 +311,7 @@ int  bpf_mtap_hdr(caddr_t, caddr_t, u_int, const struct mbuf *, u_int,
            void (*)(const void *, void *, size_t));
 int     bpf_mtap_af(caddr_t, u_int32_t, const struct mbuf *, u_int);
 int     bpf_mtap_ether(caddr_t, const struct mbuf *, u_int);
+int     bpf_tap_hdr(caddr_t, const void *, u_int, const void *, u_int, u_int);
 void    bpfattach(caddr_t *, struct ifnet *, u_int, u_int);
 void    bpfdetach(struct ifnet *);
 void   *bpfsattach(caddr_t *, const char *, u_int, u_int);