From: guy Date: Sat, 26 Feb 2005 21:58:05 +0000 (+0000) Subject: On the platforms where we do in-kernel filtering and can read more than X-Git-Tag: libpcap-0.9.1~81 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/16889bae3e84aaaf62e2c9f6dd478fdadbb953f1 On the platforms where we do in-kernel filtering and can read more than one packet from the kernel at a time, when the filter is changed, clear the libpcap buffer to discard packets read from the kernel before the filter was changed. --- diff --git a/pcap-bpf.c b/pcap-bpf.c index 1c61f7a1..b29d6c44 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.85 2005-02-24 08:59:38 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86 2005-02-26 21:58:05 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -1077,6 +1077,14 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) return (-1); } p->md.use_bpf = 1; /* filtering in the kernel */ + + /* + * Discard any previously-received packets, as they might have + * passed whatever filter was formerly in effect, but might + * not pass this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any case). + */ + p->cc = 0; return (0); } diff --git a/pcap-pf.c b/pcap-pf.c index fe21c803..23f01535 100644 --- a/pcap-pf.c +++ b/pcap-pf.c @@ -24,7 +24,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.90 2004-12-15 00:25:09 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.91 2005-02-26 21:58:06 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -567,6 +567,16 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) */ fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); p->md.use_bpf = 1; + + /* + * Discard any previously-received packets, + * as they might have passed whatever filter + * was formerly in effect, but might not pass + * this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any + * case). + */ + p->cc = 0; return (0); } diff --git a/pcap-win32.c b/pcap-win32.c index 7f45a730..f6e37cf0 100644 --- a/pcap-win32.c +++ b/pcap-win32.c @@ -32,7 +32,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.24 2004-12-17 20:41:59 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25 2005-02-26 21:58:06 guy Exp $ (LBL)"; #endif #include @@ -631,10 +631,22 @@ static int pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp) { if(PacketSetBpf(p->adapter,fp)==FALSE){ - /* kernel filter not installed. */ + /* + * Kernel filter not installed. + * XXX - fall back on userland filtering, as is done + * on other platforms? + */ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror()); return (-1); } + + /* + * Discard any previously-received packets, as they might have + * passed whatever filter was formerly in effect, but might + * not pass this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any case). + */ + p->cc = 0; return (0); }