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.
28 files changed:
*/
#if defined(SKF_AD_VLAN_TAG_PRESENT)
u_int
*/
#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
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
{
u_int wirelen, u_int buflen, const struct bpf_aux_data *aux_data _U_)
#endif
{
-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,
- return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
+ return pcap_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
* Otherwise, a bogus program could easily crash the system.
*/
int
* 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;
{
u_int i, from;
const struct bpf_insn *p;
}
return BPF_CLASS(f[len - 1].code) == BPF_RET;
}
}
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);
+}
bufp += caplen;
#endif
++pd->stat.ps_recv;
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;
#ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec;
pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec;
/*
* Validate the program.
*/
/*
* 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);
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"BPF program is not valid");
return (-1);
#endif
*/
if (pb->filtering_in_kernel ||
#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;
struct pcap_pkthdr pkthdr;
#ifdef BIOCSTSTAMP
struct bintime bt;
pkth.caplen+=sizeof(pcap_bluetooth_h4_header);
pkth.len = pkth.caplen;
if (handle->fcode.bf_insns == NULL ||
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;
}
callback(user, &pkth, pktd);
return 1;
}
bthdr->opcode = htons(hdr.opcode);
if (handle->fcode.bf_insns == NULL ||
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;
}
callback(user, &pkth, pktd);
return 1;
}
caplen = p->snapshot;
/* Run the packet filter if there is one. */
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;
/* convert between timestamp formats */
register unsigned long long ts;
gettimeofday(&pkth.ts, NULL);
if (handle->fcode.bf_insns == NULL ||
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++;
handlep->packets_read++;
callback(user, &pkth, (u_char *)raw_msg);
count++;
pcap.len = rx_len;
if (callback &&
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)))
ph = (struct packet_header *)bp;
caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
.th_wirelen ;
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;
ph->tap.th_wirelen, caplen)) {
if (cnt >= 0 && --cnt < 0)
goto out;
}
#else /* !IBMRTPC */
caplen = cc > snaplen ? snaplen : cc ;
}
#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);
if (cnt >= 0 && --cnt < 0)
goto out;
(*printit)(buf.hdr.packet, &tv, cc, caplen);
* Filtering routine that takes the auxiliary data as an additional
* argument.
*/
* 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 *);
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.
/*
* Internal interfaces for both "pcap_create()" and routines that
* open savefiles.
/* Run the packet filter if not using kernel filter */
if (handlep->filter_in_userland && handle->fcode.bf_insns) {
/* 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;
packet_len, caplen, &aux_data) == 0) {
/* rejected by filter */
return 0;
aux_data.vlan_tag_present = tp_vlan_tci_valid;
aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
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)
gettimeofday(&pkth.ts, NULL);
if (handle->fcode.bf_insns == NULL ||
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);
{
handlep->packets_read++;
callback(user, &pkth, payload);
const struct bpf_insn *pc = p->fcode.bf_insns;
++pn->rx_pkts;
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);
}
pn->cb(pn->cb_arg, h, buf);
}
caplen = nh->nh_wirelen;
if (caplen > p->snapshot)
caplen = p->snapshot;
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;
struct pcap_pkthdr h;
h.ts = nh->nh_timestamp;
h.len = nh->nh_wirelen;
* in kernel, no need to do it now - we already know
* the packet passed the filter.
*
* 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 ||
* 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) {
#ifdef ENABLE_REMOTE
switch (p->rmt_samp.method) {
/* No underlaying filtering system. We need to filter on our own */
if (p->fcode.bf_insns)
{
/* 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);
{
/* Move to next packet */
header = (dag_record_t*)((char*)header + erf_record_len);
* skipping that padding.
*/
if (pf->filtering_in_kernel ||
* 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;
struct pcap_pkthdr h;
pf->TotAccepted++;
h.ts = sp->ens_tstamp;
pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE;
if (handle->fcode.bf_insns == NULL ||
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;
callback(user, &pkth, pktd);
++priv->packets_recv;
++count;
caplen = packet_len;
}
/* Run the packet filter if there is one. */
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 :
/* get a time stamp , consisting of :
caplen = p->snapshot;
if ((p->fcode.bf_insns == NULL) ||
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;
hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision);
hdr.caplen = caplen;
hdr.len = req.length;
if (caplen > p->snapshot)
caplen = p->snapshot;
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;
struct pcap_pkthdr h;
h.ts = ntp->nh_timestamp;
h.len = nlp->nh_pktlen;
}
if (p->fcode.bf_insns == NULL ||
}
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;
struct pcap_pkthdr h;
++psn->stat.ps_recv;
h.ts.tv_sec = sh->snoop_timestamp.tv_sec;
/* No underlaying filtering system. We need to filter on our own */
if (p->fcode.bf_insns)
{
/* 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);
pkth.caplen = (bpf_u_int32)handle->snapshot;
if (handle->fcode.bf_insns == NULL ||
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);
pkth.len, pkth.caplen)) {
handlep->packets_read++;
callback(user, &pkth, handle->buffer);
pkth.ts.tv_usec = info.hdr->ts_usec;
if (handle->fcode.bf_insns == NULL ||
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);
pkth.len, pkth.caplen)) {
handlep->packets_read++;
callback(user, &pkth, handle->buffer);
pkth.ts.tv_usec = hdr->ts_usec;
if (handle->fcode.bf_insns == NULL ||
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);
pkth.len, pkth.caplen)) {
handlep->packets_read++;
callback(user, &pkth, (u_char*) hdr);
const struct bpf_insn *fcode = fp->bf_insns;
if (fcode != NULL)
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));
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#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 <net/bpf.h>, with a
- * different signature, but, on other BSD-flavored UN*Xes, it's not
- * declared in <net/bpf.h>, 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);
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);
}
if ((fcode = p->fcode.bf_insns) == NULL ||
}
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;
(*callback)(user, &h, data);
if (++n >= cnt && cnt > 0)
break;
error("%s", pcap_geterr(pd));
have_fcode = 1;
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
warn("Filter doesn't pass validation");
#ifdef BDEBUG