diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2020-06-18 23:27:59 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2020-06-18 23:27:59 +0000 |
commit | 8308c6ceb95d070dc3386327fec1b49b32dda3c7 (patch) | |
tree | 2b92bd1ba9612856abe1fff7bb730b4ec58cc998 | |
parent | 7bdc5f78da4d906fd4b6cea3cd5cb34c0b16ea9a (diff) |
extend the bpf_hdr struct to include some metadata if available.
the metadata is set if the mbuf is passed with an m_pktrhdr, and
copies the mbufs rcvif, priority, flowid. it also carries the
direction of the packet.
it also makes bpf_hdr a multiple of 4 bytes, which simplifies some
calculations a bit. it also requires no changes in userland because
libpcap just thinks the extra bytes in the header are padding and
skips over them to the payload.
this helps me verify things like whether the stack and a network
card agree about toeplitz hashes, and paves the way for doing more
interesting packet captures. being able to see where a packet came
from as it is leaving a machine is very useful.
ok mpi@
-rw-r--r-- | sys/net/bpf.c | 49 | ||||
-rw-r--r-- | sys/net/bpf.h | 31 |
2 files changed, 46 insertions, 34 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c index f2a4972af9f..e11f1f94ea3 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.c,v 1.190 2020/05/13 21:34:37 cheloha Exp $ */ +/* $OpenBSD: bpf.c,v 1.191 2020/06/18 23:27:58 dlg Exp $ */ /* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */ /* @@ -104,7 +104,7 @@ int bpfkqfilter(dev_t, struct knote *); void bpf_wakeup(struct bpf_d *); void bpf_wakeup_cb(void *); void bpf_catchpacket(struct bpf_d *, u_char *, size_t, size_t, - struct timeval *); + const struct bpf_hdr *); int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *); int bpf_setdlt(struct bpf_d *, u_int); @@ -1258,8 +1258,8 @@ bpf_mtap(caddr_t arg, const struct mbuf *m, u_int direction) struct bpf_d *d; size_t pktlen, slen; const struct mbuf *m0; - struct timeval tv; - int gottime = 0; + struct bpf_hdr tbh; + int gothdr = 0; int drop = 0; if (m == NULL) @@ -1292,17 +1292,31 @@ bpf_mtap(caddr_t arg, const struct mbuf *m, u_int direction) if (d->bd_fildrop != BPF_FILDROP_PASS) drop = 1; if (d->bd_fildrop != BPF_FILDROP_DROP) { - if (!gottime) { - if (ISSET(m->m_flags, M_PKTHDR)) + if (!gothdr) { + struct timeval tv; + memset(&tbh, 0, sizeof(tbh)); + + if (ISSET(m->m_flags, M_PKTHDR)) { + tbh.bh_ifidx = m->m_pkthdr.ph_ifidx; + tbh.bh_flowid = m->m_pkthdr.ph_flowid; + tbh.bh_flags = m->m_pkthdr.pf.prio; + if (ISSET(m->m_pkthdr.csum_flags, + M_FLOWID)) + SET(tbh.bh_flags, BPF_F_FLOWID); + m_microtime(m, &tv); - else + } else microtime(&tv); - gottime = 1; + tbh.bh_tstamp.tv_sec = tv.tv_sec; + tbh.bh_tstamp.tv_usec = tv.tv_usec; + SET(tbh.bh_flags, direction << BPF_F_DIR_SHIFT); + + gothdr = 1; } mtx_enter(&d->bd_mtx); - bpf_catchpacket(d, (u_char *)m, pktlen, slen, &tv); + bpf_catchpacket(d, (u_char *)m, pktlen, slen, &tbh); mtx_leave(&d->bd_mtx); } } @@ -1453,9 +1467,9 @@ bpf_mtap_ether(caddr_t arg, const struct mbuf *m, u_int direction) */ void bpf_catchpacket(struct bpf_d *d, u_char *pkt, size_t pktlen, size_t snaplen, - struct timeval *tv) + const struct bpf_hdr *tbh) { - struct bpf_hdr *hp; + struct bpf_hdr *bh; int totlen, curlen; int hdrlen, do_wakeup = 0; @@ -1501,17 +1515,16 @@ bpf_catchpacket(struct bpf_d *d, u_char *pkt, size_t pktlen, size_t snaplen, /* * Append the bpf header. */ - hp = (struct bpf_hdr *)(d->bd_sbuf + curlen); - hp->bh_tstamp.tv_sec = tv->tv_sec; - hp->bh_tstamp.tv_usec = tv->tv_usec; - hp->bh_datalen = pktlen; - hp->bh_hdrlen = hdrlen; + bh = (struct bpf_hdr *)(d->bd_sbuf + curlen); + *bh = *tbh; + bh->bh_datalen = pktlen; + bh->bh_hdrlen = hdrlen; + bh->bh_caplen = totlen - hdrlen; /* * Copy the packet data into the store buffer and update its length. */ - bpf_mcopy(pkt, (u_char *)hp + hdrlen, - (hp->bh_caplen = totlen - hdrlen)); + bpf_mcopy(pkt, (u_char *)bh + hdrlen, bh->bh_caplen); d->bd_slen = curlen + totlen; if (d->bd_immediate) { diff --git a/sys/net/bpf.h b/sys/net/bpf.h index 90102fc2f29..2232d1325e7 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.h,v 1.68 2019/09/30 01:53:04 dlg Exp $ */ +/* $OpenBSD: bpf.h,v 1.69 2020/06/18 23:27:58 dlg Exp $ */ /* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */ /* @@ -123,8 +123,8 @@ struct bpf_version { /* * Direction filters for BIOCSDIRFILT/BIOCGDIRFILT */ -#define BPF_DIRECTION_IN 1 -#define BPF_DIRECTION_OUT (1<<1) +#define BPF_DIRECTION_IN (1 << 0) +#define BPF_DIRECTION_OUT (1 << 1) /* * Values for BIOCGFILDROP/BIOCSFILDROP @@ -147,23 +147,22 @@ struct bpf_hdr { u_int32_t bh_datalen; /* original length of packet */ u_int16_t bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ + u_int16_t bh_ifidx; /* receive interface index */ + + u_int16_t bh_flowid; + u_int8_t bh_flags; +#define BPF_F_PRI_MASK 0x07 +#define BPF_F_FLOWID 0x08 +#define BPF_F_DIR_SHIFT 4 +#define BPF_F_DIR_MASK (0x3 << BPF_F_DIR_SHIFT) +#define BPF_F_DIR_IN (BPF_DIRECTION_IN << BPF_F_DIR_SHIFT) +#define BPF_F_DIR_OUT (BPF_DIRECTION_OUT << BPF_F_DIR_SHIFT) + u_int8_t bh_drops; }; -/* - * Because the structure above is not a multiple of 4 bytes, some compilers - * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. - * Only the kernel needs to know about it; applications use bh_hdrlen. - * XXX To save a few bytes on 32-bit machines, we avoid end-of-struct - * XXX padding by using the size of the header data elements. This is - * XXX fail-safe: on new machines, we just use the 'safe' sizeof. - */ + #ifdef _KERNEL -#if defined(__arm__) || defined(__i386__) || defined(__mips__) || \ - defined(__sparc64__) -#define SIZEOF_BPF_HDR 18 -#else #define SIZEOF_BPF_HDR sizeof(struct bpf_hdr) #endif -#endif /* * Data-link level type codes. |