Require "[wlan] dir" integer value to be within range.
Fix the != comparison for ATM and MTP field values.
Deprecate bpf_filter().
+ Require a live capture for all Linux BPF extensions.
rpcap:
Support user names and passwords in rpcap:// and rpcaps:// URLs.
Add a -t flag to rpcapd to specify the data channel port; from
/*NOTREACHED*/
}
+#ifdef __linux__
+/*
+ * This is Linux; we require PF_PACKET support. If this is a *live* capture,
+ * we can look at special meta-data in the filter expression; otherwise we
+ * can't because it is either a savefile (rfile != NULL) or a pcap_t created
+ * using pcap_open_dead() (rfile == NULL). Thus check for a flag that
+ * pcap_activate() conditionally sets.
+ */
+static void
+require_basic_bpf_extensions(compiler_state_t *cstate, const char *keyword)
+{
+ if (cstate->bpf_pcap->bpf_codegen_flags & BPF_SPECIAL_BASIC_HANDLING)
+ return;
+ bpf_error(cstate, "%s not supported on %s (not a live capture)",
+ keyword,
+ pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+}
+#endif // __linux__
+
struct block *
gen_ifindex(compiler_state_t *cstate, int ifindex)
{
break;
default:
#if defined(__linux__)
- /*
- * This is Linux; we require PF_PACKET support.
- * If this is a *live* capture, we can look at
- * special meta-data in the filter expression;
- * if it's a savefile, we can't.
- */
- if (cstate->bpf_pcap->rfile != NULL) {
- /* We have a FILE *, so this is a savefile */
- bpf_error(cstate, "ifindex not supported on %s when reading savefiles",
- pcap_datalink_val_to_description_or_dlt(cstate->linktype));
- /*NOTREACHED*/
- }
+ require_basic_bpf_extensions(cstate, "ifindex");
/* match ifindex */
b0 = gen_cmp(cstate, OR_LINKHDR, SKF_AD_OFF + SKF_AD_IFINDEX, BPF_W,
ifindex);
* in pcapng files.
*/
#if defined(__linux__)
- /*
- * This is Linux; we require PF_PACKET support.
- * If this is a *live* capture, we can look at
- * special meta-data in the filter expression;
- * if it's a savefile, we can't.
- */
- if (cstate->bpf_pcap->rfile != NULL) {
- /* We have a FILE *, so this is a savefile */
- bpf_error(cstate, "inbound/outbound not supported on %s when reading savefiles",
- pcap_datalink_val_to_description_or_dlt(cstate->linktype));
- /*NOTREACHED*/
- }
+ require_basic_bpf_extensions(cstate, outbound ? "outbound" : "inbound");
/* match outgoing packets */
b0 = gen_cmp(cstate, OR_LINKHDR, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
PACKET_OUTGOING);
* BPF code generation flags.
*/
#define BPF_SPECIAL_VLAN_HANDLING 0x00000001 /* special VLAN handling for Linux */
+/*
+ * Special handling of packet type and ifindex, which are some of the auxiliary
+ * data items available in Linux >= 2.6.27. Disregard protocol and netlink
+ * attributes for now.
+ */
+#define BPF_SPECIAL_BASIC_HANDLING 0x00000002
/*
* User data structure for the one-shot callback used for pcap_next()
*/
handle->fd = sock_fd;
-#if defined(SO_BPF_EXTENSIONS) && defined(SKF_AD_VLAN_TAG_PRESENT)
+#ifdef SO_BPF_EXTENSIONS
/*
* Can we generate special code for VLAN checks?
* (XXX - what if we need the special code but it's not supported
*/
if (getsockopt(sock_fd, SOL_SOCKET, SO_BPF_EXTENSIONS,
&bpf_extensions, &len) == 0) {
+ /*
+ * This is a live capture with some BPF extensions support,
+ * so indicate that at least the auxiliary data items from
+ * Linux 2.6.27 are available (this concerns SKF_AD_PKTTYPE
+ * and SKF_AD_IFINDEX in the first place).
+ */
+ handle->bpf_codegen_flags |= BPF_SPECIAL_BASIC_HANDLING;
+#ifdef SKF_AD_VLAN_TAG_PRESENT
if (bpf_extensions >= SKF_AD_VLAN_TAG_PRESENT) {
/*
* Yes, we can. Request that we do so.
*/
handle->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING;
}
+#endif // SKF_AD_VLAN_TAG_PRESENT
}
-#endif /* defined(SO_BPF_EXTENSIONS) && defined(SKF_AD_VLAN_TAG_PRESENT) */
+#endif // SO_BPF_EXTENSIONS
return status;
}
(004) ret #0
EOF
}, # juniper_mfr_outbound
- # The two tests below represent the current Linux-specific implementation,
- # which is not consistent in which function -- pcap_compile() or
- # pcap_setfilter() -- and under which conditions patches the bytecode for
- # specific keywords. So this behaviour may change in future.
- linux_skf_ad_inbound => {
+ inbound_linuxext => {
skip => is_not_linux(),
+ linuxext => 1,
DLT => 'EN10MB',
expr => 'inbound',
unopt => <<~'EOF',
(002) ret #0
(003) ret #262144
EOF
- }, # linux_skf_ad_inbound
- linux_skf_ad_outbound => {
+ }, # inbound_linuxext
+ outbound_linuxext => {
skip => is_not_linux(),
+ linuxext => 1,
DLT => 'EN10MB',
expr => 'outbound',
unopt => <<~'EOF',
(002) ret #262144
(003) ret #0
EOF
- }, # linux_skf_ad_inbound
+ }, # outbound_linuxext
+ ifindex_linuxext => {
+ skip => is_not_linux(),
+ linuxext => 1,
+ DLT => 'EN10MB',
+ expr => 'ifindex 10',
+ unopt => <<~'EOF',
+ (000) ld [ifidx]
+ (001) jeq #0xa jt 2 jf 3
+ (002) ret #262144
+ (003) ret #0
+ EOF
+ }, # ifindex_linuxext
mtp2_fisu => {
DLT => 'MTP2',
expr => 'mpls 1048576',
errstr => 'greater than maximum',
},
- inbound_not_supported => {
+ inbound_not_supported_linux => {
+ skip => is_not_linux(),
+ DLT => 'EN10MB',
+ expr => 'inbound',
+ errstr => 'not a live capture',
+ },
+ outbound_not_supported_linux => {
+ skip => is_not_linux(),
+ DLT => 'EN10MB',
+ expr => 'outbound',
+ errstr => 'not a live capture',
+ },
+ ifindex_not_supported_linux => {
+ skip => is_not_linux(),
+ DLT => 'LINUX_SLL',
+ expr => 'ifindex 1',
+ errstr => 'not a live capture',
+ },
+ inbound_not_supported_other => {
skip => is_linux(),
DLT => 'EN10MB',
expr => 'inbound',
- errstr => 'inbound/outbound not supported',
+ errstr => 'not supported',
},
- outbound_not_supported => {
+ outbound_not_supported_other => {
skip => is_linux(),
DLT => 'EN10MB',
expr => 'outbound',
- errstr => 'inbound/outbound not supported',
+ errstr => 'not supported',
+ },
+ ifindex_not_supported_other => {
+ skip => is_linux(),
+ DLT => 'EN10MB',
+ expr => 'ifindex 1',
+ errstr => 'not supported',
},
);
#ifdef LINUX_BPF_EXT
if (lflag) {
pd->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING;
+ pd->bpf_codegen_flags |= BPF_SPECIAL_BASIC_HANDLING;
}
#endif