From: Guy Harris Date: Sat, 1 Sep 2018 03:08:50 +0000 (-0700) Subject: Clean up the declaration of the packet-filtering routines. X-Git-Tag: libpcap-1.10-bp~855 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/1131a7c26c6f4d4772e4a2beeaf7212f4dea74ac Clean up the declaration of the packet-filtering routines. If net/bpf.h declares bpf_filter() one way and libpcap defines it another way, even pcap-bpf.c needs a declaration that matches how libpcap defines it, not how net/bpf.h (mistakenly) declares it. ("Mistakenly" because it should *not* be declaring the kernel's version of bpf_filter() unless it's being used in a *kernel* build; other *BSDs, and macOS, declare it only in kernel builds by testing for a #define such as KERNEL or KERNEL_PRIVATE, but NetBSD doesn't - it *should*, but it doesn't.) So we rename the internal-to-pcap filtering routine as pcap_filter(), which is not exported from libpcap, and have bpf_filter() be a wrapper around pcap_filter() that is exported. Use pcap_filter(), rather than bpf_filter(), for all filtering inside libpcap (except for filtering that uses bpf_filter_with_aux_data(), which we rename pcap_filter_with_aux_data()). Do the same for bpf_validate(), which is *also* declared in net/bpf.h, even for non-kernel builds, in NetBSD. As we're not exporting pcap_filter_with_aux_data(), don't even *declare* it in a public header; don't declare struct bpf_aux_data in a public header, either. That way we can change it without worrying about breaking APIs or ABIs; we may do that if, for example, we want to support the "inbound" and "outbound" filters when reading pcapng files, adding a direction indicator to that structure. Declare bpf_filter() in pcap/bpf.h even on NetBSD and QNX; pcap-bpf.c doesn't include pcap/bpf.h (it sets a #define to force pcap/pcap.h not to include it), so we won't get any collisions if net/bpf.h (which it does include) declares it. The only collisions will occur in programs that include *both* pcap/pcap.h or pcap/bpf.h *and* net/bpf.h, and that will occur only if net/bpf.h declares bpf_filter() even when building userland code, and the correct fix for *that* is to fix net/bpf.h not to declare them in non-kernel builds. --- diff --git a/bpf_filter.c b/bpf_filter.c index 93c33764..e5c286b5 100644 --- a/bpf_filter.c +++ b/bpf_filter.c @@ -85,11 +85,11 @@ enum { */ #if defined(SKF_AD_VLAN_TAG_PRESENT) u_int -bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, +pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, u_int wirelen, u_int buflen, const struct bpf_aux_data *aux_data) #else u_int -bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, +pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, u_int wirelen, u_int buflen, const struct bpf_aux_data *aux_data _U_) #endif { @@ -370,10 +370,10 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, } u_int -bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, +pcap_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, u_int buflen) { - return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL); + return pcap_filter_with_aux_data(pc, p, wirelen, buflen, NULL); } /* @@ -388,7 +388,7 @@ bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, * Otherwise, a bogus program could easily crash the system. */ int -bpf_validate(const struct bpf_insn *f, int len) +pcap_validate_filter(const struct bpf_insn *f, int len) { u_int i, from; const struct bpf_insn *p; @@ -510,3 +510,19 @@ bpf_validate(const struct bpf_insn *f, int len) } return BPF_CLASS(f[len - 1].code) == BPF_RET; } + +/* + * Exported because older versions of libpcap exported them. + */ +u_int +bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, + u_int buflen) +{ + return pcap_filter(pc, p, wirelen, buflen); +} + +int +bpf_validate(const struct bpf_insn *f, int len) +{ + return pcap_validate_filter(f, len); +} diff --git a/dlpisubs.c b/dlpisubs.c index a049ef87..b39c3d34 100644 --- a/dlpisubs.c +++ b/dlpisubs.c @@ -190,7 +190,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user, bufp += caplen; #endif ++pd->stat.ps_recv; - if (bpf_filter(p->fcode.bf_insns, pk, origlen, caplen)) { + if (pcap_filter(p->fcode.bf_insns, pk, origlen, caplen)) { #ifdef HAVE_SYS_BUFMOD_H pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; diff --git a/optimize.c b/optimize.c index 947a3993..fa8e0ac1 100644 --- a/optimize.c +++ b/optimize.c @@ -2359,7 +2359,7 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp) /* * Validate the program. */ - if (!bpf_validate(fp->bf_insns, fp->bf_len)) { + if (!pcap_validate_filter(fp->bf_insns, fp->bf_len)) { pcap_snprintf(p->errbuf, sizeof(p->errbuf), "BPF program is not valid"); return (-1); diff --git a/pcap-bpf.c b/pcap-bpf.c index 6ce383b0..5e9f6899 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -1116,7 +1116,7 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) #endif */ if (pb->filtering_in_kernel || - bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { + pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { struct pcap_pkthdr pkthdr; #ifdef BIOCSTSTAMP struct bintime bt; diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c index 15c2c1c5..0c21d9c1 100644 --- a/pcap-bt-linux.c +++ b/pcap-bt-linux.c @@ -370,7 +370,7 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char pkth.caplen+=sizeof(pcap_bluetooth_h4_header); pkth.len = pkth.caplen; if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { + pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { callback(user, &pkth, pktd); return 1; } diff --git a/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c index c222c100..4f127127 100644 --- a/pcap-bt-monitor-linux.c +++ b/pcap-bt-monitor-linux.c @@ -139,7 +139,7 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch bthdr->opcode = htons(hdr.opcode); if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { + pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { callback(user, &pkth, pktd); return 1; } diff --git a/pcap-dag.c b/pcap-dag.c index 30983a69..be784b46 100644 --- a/pcap-dag.c +++ b/pcap-dag.c @@ -672,7 +672,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) caplen = p->snapshot; /* Run the packet filter if there is one. */ - if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { + if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { /* convert between timestamp formats */ register unsigned long long ts; diff --git a/pcap-dbus.c b/pcap-dbus.c index 1252975e..9f426e67 100644 --- a/pcap-dbus.c +++ b/pcap-dbus.c @@ -91,7 +91,7 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us gettimeofday(&pkth.ts, NULL); if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) { + pcap_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, (u_char *)raw_msg); count++; diff --git a/pcap-dos.c b/pcap-dos.c index b1b9ecd7..aafba0c6 100644 --- a/pcap-dos.c +++ b/pcap-dos.c @@ -283,7 +283,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data) pcap.len = rx_len; if (callback && - (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen))) + (!p->fcode.bf_insns || pcap_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen))) { filter_count++; diff --git a/pcap-enet.c b/pcap-enet.c index cd8cdbbb..6f0512f3 100644 --- a/pcap-enet.c +++ b/pcap-enet.c @@ -75,7 +75,7 @@ readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit) ph = (struct packet_header *)bp; caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap .th_wirelen ; - if (bpf_filter(fcode, (char *)ph->packet, + if (pcap_filter(fcode, (char *)ph->packet, ph->tap.th_wirelen, caplen)) { if (cnt >= 0 && --cnt < 0) goto out; @@ -89,7 +89,7 @@ readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit) } #else /* !IBMRTPC */ caplen = cc > snaplen ? snaplen : cc ; - if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) { + if (pcap_filter(fcode, buf.hdr.packet, cc, caplen)) { if (cnt >= 0 && --cnt < 0) goto out; (*printit)(buf.hdr.packet, &tv, cc, caplen); diff --git a/pcap-int.h b/pcap-int.h index 9fbc6fb2..2426ab10 100644 --- a/pcap-int.h +++ b/pcap-int.h @@ -496,9 +496,19 @@ struct bpf_aux_data { * Filtering routine that takes the auxiliary data as an additional * argument. */ -u_int bpf_filter_with_aux_data(const struct bpf_insn *, +u_int pcap_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); +/* + * Filtering routine that doesn't. + */ +u_int pcap_filter(const struct bpf_insn *, const u_char *, u_int, u_int); + +/* + * Routine to validate a BPF program. + */ +int pcap_validate_filter(const struct bpf_insn *, int); + /* * Internal interfaces for both "pcap_create()" and routines that * open savefiles. diff --git a/pcap-linux.c b/pcap-linux.c index 759440de..54592e66 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -2045,7 +2045,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) /* Run the packet filter if not using kernel filter */ if (handlep->filter_in_userland && handle->fcode.bf_insns) { - if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp, + if (pcap_filter_with_aux_data(handle->fcode.bf_insns, bp, packet_len, caplen, &aux_data) == 0) { /* rejected by filter */ return 0; @@ -5143,11 +5143,11 @@ static int pcap_handle_packet_mmap( aux_data.vlan_tag_present = tp_vlan_tci_valid; aux_data.vlan_tag = tp_vlan_tci & 0x0fff; - if (bpf_filter_with_aux_data(handle->fcode.bf_insns, - bp, - tp_len, - snaplen, - &aux_data) == 0) + if (pcap_filter_with_aux_data(handle->fcode.bf_insns, + bp, + tp_len, + snaplen, + &aux_data) == 0) return 0; } diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c index d5c5dcdc..675df4ae 100644 --- a/pcap-netfilter-linux.c +++ b/pcap-netfilter-linux.c @@ -240,7 +240,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c gettimeofday(&pkth.ts, NULL); if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen)) + pcap_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, payload); diff --git a/pcap-netmap.c b/pcap-netmap.c index f1505633..a577d2c6 100644 --- a/pcap-netmap.c +++ b/pcap-netmap.c @@ -82,7 +82,7 @@ pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf) const struct bpf_insn *pc = p->fcode.bf_insns; ++pn->rx_pkts; - if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen)) + if (pc == NULL || pcap_filter(pc, buf, h->len, h->caplen)) pn->cb(pn->cb_arg, h, buf); } diff --git a/pcap-nit.c b/pcap-nit.c index 6a1a77c2..c011a6a5 100644 --- a/pcap-nit.c +++ b/pcap-nit.c @@ -179,7 +179,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) caplen = nh->nh_wirelen; if (caplen > p->snapshot) caplen = p->snapshot; - if (bpf_filter(p->fcode.bf_insns, cp, nh->nh_wirelen, caplen)) { + if (pcap_filter(p->fcode.bf_insns, cp, nh->nh_wirelen, caplen)) { struct pcap_pkthdr h; h.ts = nh->nh_timestamp; h.len = nh->nh_wirelen; diff --git a/pcap-npf.c b/pcap-npf.c index a9ff0ff4..347c537a 100644 --- a/pcap-npf.c +++ b/pcap-npf.c @@ -585,13 +585,13 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) * in kernel, no need to do it now - we already know * the packet passed the filter. * - * XXX - bpf_filter() should always return TRUE if + * XXX - pcap_filter() should always return TRUE if * handed a null pointer for the program, but it might * just try to "run" the filter, so we check here. */ if (pw->filtering_in_kernel || p->fcode.bf_insns == NULL || - bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { + pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { #ifdef ENABLE_REMOTE switch (p->rmt_samp.method) { @@ -798,7 +798,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) /* No underlaying filtering system. We need to filter on our own */ if (p->fcode.bf_insns) { - if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) + if (pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) { /* Move to next packet */ header = (dag_record_t*)((char*)header + erf_record_len); diff --git a/pcap-pf.c b/pcap-pf.c index 5cb9433b..c712460f 100644 --- a/pcap-pf.c +++ b/pcap-pf.c @@ -201,7 +201,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) * skipping that padding. */ if (pf->filtering_in_kernel || - bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { + pcap_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { struct pcap_pkthdr h; pf->TotAccepted++; h.ts = sp->ens_tstamp; diff --git a/pcap-rdmasniff.c b/pcap-rdmasniff.c index c50fe3fd..921e68c6 100644 --- a/pcap-rdmasniff.c +++ b/pcap-rdmasniff.c @@ -156,7 +156,7 @@ rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE; if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { + pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { callback(user, &pkth, pktd); ++priv->packets_recv; ++count; diff --git a/pcap-septel.c b/pcap-septel.c index 0471153f..dd03e23e 100644 --- a/pcap-septel.c +++ b/pcap-septel.c @@ -135,7 +135,7 @@ loop: caplen = packet_len; } /* Run the packet filter if there is one. */ - if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { + if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { /* get a time stamp , consisting of : diff --git a/pcap-snf.c b/pcap-snf.c index 4eae0b39..3d4fea9f 100644 --- a/pcap-snf.c +++ b/pcap-snf.c @@ -177,7 +177,7 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) caplen = p->snapshot; if ((p->fcode.bf_insns == NULL) || - bpf_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) { + pcap_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) { hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision); hdr.caplen = caplen; hdr.len = req.length; diff --git a/pcap-snit.c b/pcap-snit.c index 9c6fbd48..8f2280f5 100644 --- a/pcap-snit.c +++ b/pcap-snit.c @@ -190,7 +190,7 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) if (caplen > p->snapshot) caplen = p->snapshot; - if (bpf_filter(p->fcode.bf_insns, cp, nlp->nh_pktlen, caplen)) { + if (pcap_filter(p->fcode.bf_insns, cp, nlp->nh_pktlen, caplen)) { struct pcap_pkthdr h; h.ts = ntp->nh_timestamp; h.len = nlp->nh_pktlen; diff --git a/pcap-snoop.c b/pcap-snoop.c index a598bae5..f140bfc5 100644 --- a/pcap-snoop.c +++ b/pcap-snoop.c @@ -126,7 +126,7 @@ again: } if (p->fcode.bf_insns == NULL || - bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { + pcap_filter(p->fcode.bf_insns, cp, datalen, caplen)) { struct pcap_pkthdr h; ++psn->stat.ps_recv; h.ts.tv_sec = sh->snoop_timestamp.tv_sec; diff --git a/pcap-tc.c b/pcap-tc.c index 38c70245..a1f58911 100644 --- a/pcap-tc.c +++ b/pcap-tc.c @@ -985,7 +985,7 @@ static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user) /* No underlaying filtering system. We need to filter on our own */ if (p->fcode.bf_insns) { - filterResult = bpf_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength); + filterResult = pcap_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength); if (filterResult == 0) { diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index b92c05ea..3412f243 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -912,7 +912,7 @@ got: pkth.caplen = (bpf_u_int32)handle->snapshot; if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, handle->buffer, + pcap_filter(handle->fcode.bf_insns, handle->buffer, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, handle->buffer); @@ -1081,7 +1081,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u pkth.ts.tv_usec = info.hdr->ts_usec; if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, handle->buffer, + pcap_filter(handle->fcode.bf_insns, handle->buffer, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, handle->buffer); @@ -1163,7 +1163,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch pkth.ts.tv_usec = hdr->ts_usec; if (handle->fcode.bf_insns == NULL || - bpf_filter(handle->fcode.bf_insns, (u_char*) hdr, + pcap_filter(handle->fcode.bf_insns, (u_char*) hdr, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, (u_char*) hdr); diff --git a/pcap.c b/pcap.c index 95a9f7c0..204408a7 100644 --- a/pcap.c +++ b/pcap.c @@ -3682,7 +3682,7 @@ pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, const struct bpf_insn *fcode = fp->bf_insns; if (fcode != NULL) - return (bpf_filter(fcode, pkt, h->len, h->caplen)); + return (pcap_filter(fcode, pkt, h->len, h->caplen)); else return (0); } diff --git a/pcap/bpf.h b/pcap/bpf.h index 6cb5b7d2..b37546bf 100644 --- a/pcap/bpf.h +++ b/pcap/bpf.h @@ -244,16 +244,7 @@ struct bpf_insn { #define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } -/* - * On at least some versions of NetBSD and QNX, we don't want to declare - * bpf_filter() here, as it's also be declared in , with a - * different signature, but, on other BSD-flavored UN*Xes, it's not - * declared in , so we *do* want to declare it here, so it's - * declared when we build pcap-bpf.c. - */ -#if !defined(__NetBSD__) && !defined(__QNX__) - PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#endif +PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); PCAP_API int bpf_validate(const struct bpf_insn *f, int len); PCAP_API char *bpf_image(const struct bpf_insn *, int); PCAP_API void bpf_dump(const struct bpf_program *, int); diff --git a/savefile.c b/savefile.c index 830669ec..15b1f183 100644 --- a/savefile.c +++ b/savefile.c @@ -501,7 +501,7 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) } if ((fcode = p->fcode.bf_insns) == NULL || - bpf_filter(fcode, data, h.len, h.caplen)) { + pcap_filter(fcode, data, h.len, h.caplen)) { (*callback)(user, &h, data); if (++n >= cnt && cnt > 0) break; diff --git a/testprogs/filtertest.c b/testprogs/filtertest.c index 7e2d6d6e..4fcf3ff0 100644 --- a/testprogs/filtertest.c +++ b/testprogs/filtertest.c @@ -318,7 +318,7 @@ main(int argc, char **argv) error("%s", pcap_geterr(pd)); have_fcode = 1; - if (!bpf_validate(fcode.bf_insns, fcode.bf_len)) + if (!pcap_validate_filter(fcode.bf_insns, fcode.bf_len)) warn("Filter doesn't pass validation"); #ifdef BDEBUG