mirror of
https://github.com/domcyrus/rustnet.git
synced 2026-01-05 21:40:01 -06:00
fix(macos): skip PKTAP when BPF filter is specified (#100)
BPF filters are incompatible with PKTAP (linktype 149) on macOS. When a filter is specified, fall back to regular interface capture.
This commit is contained in:
13
USAGE.md
13
USAGE.md
@@ -177,10 +177,17 @@ Apply a BPF (Berkeley Packet Filter) expression to filter packets at capture tim
|
||||
**Common filter expressions:**
|
||||
|
||||
```bash
|
||||
# Filter by port
|
||||
# Filter by port (matches source OR destination)
|
||||
rustnet --bpf-filter "port 443"
|
||||
rustnet --bpf-filter "port 80 or port 8080"
|
||||
|
||||
# Filter by destination port specifically
|
||||
rustnet --bpf-filter "dst port 443"
|
||||
rustnet --bpf-filter "tcp dst port 80"
|
||||
|
||||
# Filter by source port specifically
|
||||
rustnet --bpf-filter "src port 443"
|
||||
|
||||
# Filter by host
|
||||
rustnet --bpf-filter "host 192.168.1.1"
|
||||
rustnet --bpf-filter "net 10.0.0.0/8"
|
||||
@@ -196,7 +203,9 @@ rustnet --bpf-filter "tcp port 443 and host github.com"
|
||||
rustnet --bpf-filter "not port 22"
|
||||
```
|
||||
|
||||
**Note:** BPF filter syntax follows the pcap-filter(7) format. Invalid filters will cause RustNet to exit with an error. Use `man pcap-filter` for complete syntax documentation.
|
||||
**Notes:**
|
||||
- BPF filter syntax follows the pcap-filter(7) format. Invalid filters will cause RustNet to exit with an error. Use `man pcap-filter` for complete syntax documentation.
|
||||
- **macOS limitation:** BPF filters are incompatible with PKTAP (linktype 149). When you specify a BPF filter on macOS, RustNet automatically falls back to regular interface capture. This means process identification uses `lsof` instead of PKTAP's direct process metadata, which may be slightly less accurate for short-lived connections.
|
||||
|
||||
#### `-l, --log-level <LEVEL>`
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ pub fn build_cli() -> Command {
|
||||
.short('f')
|
||||
.long("bpf-filter")
|
||||
.value_name("FILTER")
|
||||
.help("BPF filter expression for packet capture (e.g., \"tcp port 443\")")
|
||||
.help("BPF filter expression for packet capture (e.g., \"tcp port 443\", \"dst port 80\"). Note: On macOS, using a BPF filter disables PKTAP (process info falls back to lsof)")
|
||||
.required(false),
|
||||
)
|
||||
.arg(
|
||||
|
||||
@@ -162,9 +162,11 @@ fn find_best_device() -> Result<Device> {
|
||||
|
||||
/// Setup packet capture with the given configuration
|
||||
pub fn setup_packet_capture(config: CaptureConfig) -> Result<(Capture<Active>, String, i32)> {
|
||||
// Try PKTAP first on macOS for process metadata, but only when no interface is explicitly specified
|
||||
// Try PKTAP first on macOS for process metadata, but only when:
|
||||
// - No interface is explicitly specified
|
||||
// - No BPF filter is specified (BPF filters don't work with PKTAP's linktype 149)
|
||||
#[cfg(target_os = "macos")]
|
||||
if config.interface.is_none() {
|
||||
if config.interface.is_none() && config.filter.is_none() {
|
||||
log::info!("Attempting to use PKTAP for process metadata on macOS");
|
||||
|
||||
match Capture::from_device("pktap") {
|
||||
@@ -227,6 +229,10 @@ pub fn setup_packet_capture(config: CaptureConfig) -> Result<(Capture<Active>, S
|
||||
}
|
||||
|
||||
// Fallback to regular capture (original code)
|
||||
#[cfg(target_os = "macos")]
|
||||
if config.filter.is_some() {
|
||||
log::warn!("BPF filter specified - using regular capture instead of PKTAP (BPF filters don't work with PKTAP)");
|
||||
}
|
||||
log::info!("Setting up regular packet capture");
|
||||
let device = find_capture_device(&config.interface)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user