diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-11-03 20:00:19 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-11-03 20:00:19 +0000 |
commit | d800cbd157ae776892caa95f34727945ca3d1aaf (patch) | |
tree | 0e310e22b7bb1217fb33464d1829221ee48ff2c0 /sys/net | |
parent | afb982b6101e1d87540dc498a098618c34d30b0e (diff) |
re-implement the bpf "filter drop" option that it actually works. the
bpf FILDROP interface exists for about one year but the required
interface to the drivers was missing - so it was useless. this new
approach based on a design by henning@ uses a new mbuf flag to mark
filtered packets and to drop them in the generic network stack input
routines (like ether_input).
for example; after some additional testing, this could be used by
dhclient to filter everything except DHCP packets (track tech@
for a corresponding dhclient diff). the "filter dropped" packets won't
reach the network stack. so it's probably some kind of a very basic
application layer packet filter ;).
ok canacar@, discussed with henning@ and others
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/bpf.c | 21 | ||||
-rw-r--r-- | sys/net/bpf.h | 8 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 10 |
3 files changed, 23 insertions, 16 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c index f329bde00b6..c7ff40f28f6 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.c,v 1.59 2005/07/31 03:52:18 pascoe Exp $ */ +/* $OpenBSD: bpf.c,v 1.60 2005/11/03 20:00:18 reyk Exp $ */ /* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */ /* @@ -1157,17 +1157,16 @@ bpf_mcopy(const void *src_arg, void *dst_arg, size_t len) /* * Incoming linkage from device drivers, when packet is in an mbuf chain. */ -int +void bpf_mtap(caddr_t arg, struct mbuf *m) { struct bpf_if *bp = (struct bpf_if *)arg; struct bpf_d *d; size_t pktlen, slen; struct mbuf *m0; - int drop = 0; if (m == NULL) - return (0); + return; pktlen = 0; for (m0 = m; m0 != 0; m0 = m0->m_next) @@ -1182,10 +1181,8 @@ bpf_mtap(caddr_t arg, struct mbuf *m) bpf_catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); if (d->bd_fildrop) - drop++; + m->m_flags |= M_FILDROP; } - - return (drop); } /* @@ -1197,7 +1194,7 @@ bpf_mtap(caddr_t arg, struct mbuf *m) * fields in this header that we initialize, and will not try to free * it or keep a pointer to it. */ -int +void bpf_mtap_hdr(caddr_t arg, caddr_t data, u_int dlen, struct mbuf *m) { struct m_hdr mh; @@ -1207,7 +1204,8 @@ bpf_mtap_hdr(caddr_t arg, caddr_t data, u_int dlen, struct mbuf *m) mh.mh_len = dlen; mh.mh_data = data; - return bpf_mtap(arg, (struct mbuf *) &mh); + bpf_mtap(arg, (struct mbuf *) &mh); + m->m_flags |= mh.mh_flags & M_FILDROP; } /* @@ -1219,7 +1217,7 @@ bpf_mtap_hdr(caddr_t arg, caddr_t data, u_int dlen, struct mbuf *m) * fields in this header that we initialize, and will not try to free * it or keep a pointer to it. */ -int +void bpf_mtap_af(caddr_t arg, u_int32_t af, struct mbuf *m) { struct m_hdr mh; @@ -1229,7 +1227,8 @@ bpf_mtap_af(caddr_t arg, u_int32_t af, struct mbuf *m) mh.mh_len = 4; mh.mh_data = (caddr_t)⁡ - return bpf_mtap(arg, (struct mbuf *) &mh); + bpf_mtap(arg, (struct mbuf *) &mh); + m->m_flags |= mh.mh_flags & M_FILDROP; } /* diff --git a/sys/net/bpf.h b/sys/net/bpf.h index b6e8c0e1610..3a435af6ed4 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.h,v 1.31 2005/07/31 03:52:18 pascoe Exp $ */ +/* $OpenBSD: bpf.h,v 1.32 2005/11/03 20:00:18 reyk Exp $ */ /* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */ /* @@ -261,9 +261,9 @@ struct bpf_dltlist { #ifdef _KERNEL int bpf_validate(struct bpf_insn *, int); int bpf_tap(caddr_t, u_char *, u_int); -int bpf_mtap(caddr_t, struct mbuf *); -int bpf_mtap_hdr(caddr_t, caddr_t, u_int, struct mbuf *); -int bpf_mtap_af(caddr_t, u_int32_t, struct mbuf *); +void bpf_mtap(caddr_t, struct mbuf *); +void bpf_mtap_hdr(caddr_t, caddr_t, u_int, struct mbuf *); +void bpf_mtap_af(caddr_t, u_int32_t, struct mbuf *); void bpfattach(caddr_t *, struct ifnet *, u_int, u_int); void bpfdetach(struct ifnet *); void bpfilterattach(int); diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 6a7eeed9407..ee4bbf4c1d2 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.98 2005/10/17 08:43:35 henning Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.99 2005/11/03 20:00:18 reyk Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -615,6 +615,14 @@ ether_input(ifp, eh, m) ac = (struct arpcom *)ifp; /* + * If packet has been filtered by the bpf listener, drop it now + */ + if (m->m_flags & M_FILDROP) { + m_free(m); + return; + } + + /* * If packet is unicast and we're in promiscuous mode, make sure it * is for us. Drop otherwise. */ |