From 2e57c8da991b0949809b93c622e5160c8c23f82d Mon Sep 17 00:00:00 2001 From: Krish Sharma Date: Tue, 8 Jul 2025 00:49:40 -0400 Subject: [PATCH] feat: add examples and sample data for testing and demonstration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example Programs: - standalone-demo.rs: Non-eBPF demo for testing core logic - test-traffic.rs: Traffic generation for testing - macos-demo.rs: macOS-compatible demonstration Sample Log Data: - sample_traffic.jsonl: Basic traffic examples in JSONL format - sample_traffic.csv: CSV format examples for spreadsheet analysis - comprehensive_traffic.jsonl: Complex traffic patterns with multiple protocols - threat_traffic.jsonl: Examples triggering threat detection (port scanning, etc.) Demonstration Features: - Multi-protocol traffic examples (TCP, UDP, ICMP, GRE, ESP, AH) - Port scanning simulation for threat detection testing - High-volume traffic patterns for performance analysis - Realistic IP addresses and network patterns - Flow correlation examples with unique hashes Use Cases: - Development testing without requiring eBPF environment - Log analysis script validation and testing - Threat detection algorithm verification - Performance benchmarking and optimization - Documentation and training examples šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../examples/comprehensive_traffic.jsonl | 53 ++++ traffic-monitor/examples/macos-demo.rs | 116 +++++++ traffic-monitor/examples/sample_traffic.csv | 11 + traffic-monitor/examples/sample_traffic.jsonl | 10 + traffic-monitor/examples/standalone-demo.rs | 290 ++++++++++++++++++ traffic-monitor/examples/test-traffic.rs | 62 ++++ traffic-monitor/examples/threat_traffic.jsonl | 29 ++ 7 files changed, 571 insertions(+) create mode 100644 traffic-monitor/examples/comprehensive_traffic.jsonl create mode 100644 traffic-monitor/examples/macos-demo.rs create mode 100644 traffic-monitor/examples/sample_traffic.csv create mode 100644 traffic-monitor/examples/sample_traffic.jsonl create mode 100644 traffic-monitor/examples/standalone-demo.rs create mode 100644 traffic-monitor/examples/test-traffic.rs create mode 100644 traffic-monitor/examples/threat_traffic.jsonl diff --git a/traffic-monitor/examples/comprehensive_traffic.jsonl b/traffic-monitor/examples/comprehensive_traffic.jsonl new file mode 100644 index 00000000..6deb2fa7 --- /dev/null +++ b/traffic-monitor/examples/comprehensive_traffic.jsonl @@ -0,0 +1,53 @@ +{"timestamp": 1732834800, "timestamp_iso": "2024-11-29T10:00:00.000Z", "src_ip": "8.8.8.8", "dst_ip": "192.168.1.100", "src_port": 53, "dst_port": 12345, "protocol": "UDP", "protocol_num": 17, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a1b2c3d4"} +{"timestamp": 1732834801, "timestamp_iso": "2024-11-29T10:00:01.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 443, "dst_port": 54321, "protocol": "TCP", "protocol_num": 6, "packet_size": 1500, "action": "DROP", "interface": "eth0", "flow_hash": "b2c3d4e5"} +{"timestamp": 1732834802, "timestamp_iso": "2024-11-29T10:00:02.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c3d4e5f6"} +{"timestamp": 1732834803, "timestamp_iso": "2024-11-29T10:00:03.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 22, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "d4e5f6a7"} +{"timestamp": 1732834804, "timestamp_iso": "2024-11-29T10:00:04.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 23, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "e5f6a7b8"} +{"timestamp": 1732834805, "timestamp_iso": "2024-11-29T10:00:05.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 25, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "f6a7b8c9"} +{"timestamp": 1732834806, "timestamp_iso": "2024-11-29T10:00:06.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 53, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "a7b8c9d0"} +{"timestamp": 1732834807, "timestamp_iso": "2024-11-29T10:00:07.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 79, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "b8c9d0e1"} +{"timestamp": 1732834808, "timestamp_iso": "2024-11-29T10:00:08.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 135, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c9d0e1f2"} +{"timestamp": 1732834809, "timestamp_iso": "2024-11-29T10:00:09.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 139, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "d0e1f2a3"} +{"timestamp": 1732834810, "timestamp_iso": "2024-11-29T10:00:10.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 445, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "e1f2a3b4"} +{"timestamp": 1732834811, "timestamp_iso": "2024-11-29T10:00:11.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 1433, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "f2a3b4c5"} +{"timestamp": 1732834812, "timestamp_iso": "2024-11-29T10:00:12.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 3389, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "a3b4c5d6"} +{"timestamp": 1732834813, "timestamp_iso": "2024-11-29T10:00:13.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 5432, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "b4c5d6e7"} +{"timestamp": 1732834814, "timestamp_iso": "2024-11-29T10:00:14.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 3306, "dst_port": 8080, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c5d6e7f8"} +{"timestamp": 1732834815, "timestamp_iso": "2024-11-29T10:00:15.000Z", "src_ip": "198.51.100.42", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 45678, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "LOG", "interface": "eth0", "flow_hash": "d6e7f8a9"} +{"timestamp": 1732834816, "timestamp_iso": "2024-11-29T10:00:16.000Z", "src_ip": "198.51.100.42", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 45679, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "LOG", "interface": "eth0", "flow_hash": "e7f8a9b0"} +{"timestamp": 1732834817, "timestamp_iso": "2024-11-29T10:00:17.000Z", "src_ip": "198.51.100.42", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 45680, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "LOG", "interface": "eth0", "flow_hash": "f8a9b0c1"} +{"timestamp": 1732834818, "timestamp_iso": "2024-11-29T10:00:18.000Z", "src_ip": "198.51.100.42", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 45681, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "LOG", "interface": "eth0", "flow_hash": "a9b0c1d2"} +{"timestamp": 1732834819, "timestamp_iso": "2024-11-29T10:00:19.000Z", "src_ip": "198.51.100.42", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 45682, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "LOG", "interface": "eth0", "flow_hash": "b0c1d2e3"} +{"timestamp": 1732834820, "timestamp_iso": "2024-11-29T10:00:20.000Z", "src_ip": "8.8.8.8", "dst_ip": "192.168.1.101", "src_port": 53, "dst_port": 12346, "protocol": "UDP", "protocol_num": 17, "packet_size": 256, "action": "LOG", "interface": "eth0", "flow_hash": "c1d2e3f4"} +{"timestamp": 1732834821, "timestamp_iso": "2024-11-29T10:00:21.000Z", "src_ip": "8.8.4.4", "dst_ip": "192.168.1.102", "src_port": 53, "dst_port": 12347, "protocol": "UDP", "protocol_num": 17, "packet_size": 512, "action": "LOG", "interface": "wlan0", "flow_hash": "d2e3f4a5"} +{"timestamp": 1732834822, "timestamp_iso": "2024-11-29T10:00:22.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 22, "dst_port": 54323, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "DROP", "interface": "eth0", "flow_hash": "e3f4a5b6"} +{"timestamp": 1732834823, "timestamp_iso": "2024-11-29T10:00:23.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 443, "dst_port": 54324, "protocol": "TCP", "protocol_num": 6, "packet_size": 1200, "action": "LOG", "interface": "eth0", "flow_hash": "f4a5b6c7"} +{"timestamp": 1732834824, "timestamp_iso": "2024-11-29T10:00:24.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 25, "dst_port": 54325, "protocol": "TCP", "protocol_num": 6, "packet_size": 800, "action": "DROP", "interface": "eth0", "flow_hash": "a5b6c7d8"} +{"timestamp": 1732834825, "timestamp_iso": "2024-11-29T10:00:25.000Z", "src_ip": "47.254.33.187", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 445, "protocol": "TCP", "protocol_num": 6, "packet_size": 1460, "action": "LOG", "interface": "eth0", "flow_hash": "b6c7d8e9"} +{"timestamp": 1732834826, "timestamp_iso": "2024-11-29T10:00:26.000Z", "src_ip": "47.254.33.187", "dst_ip": "192.168.1.100", "src_port": 12346, "dst_port": 445, "protocol": "TCP", "protocol_num": 6, "packet_size": 1460, "action": "LOG", "interface": "eth0", "flow_hash": "c7d8e9f0"} +{"timestamp": 1732834827, "timestamp_iso": "2024-11-29T10:00:27.000Z", "src_ip": "47.254.33.187", "dst_ip": "192.168.1.100", "src_port": 12347, "dst_port": 445, "protocol": "TCP", "protocol_num": 6, "packet_size": 1460, "action": "LOG", "interface": "eth0", "flow_hash": "d8e9f0a1"} +{"timestamp": 1732834828, "timestamp_iso": "2024-11-29T10:00:28.000Z", "src_ip": "47.254.33.187", "dst_ip": "192.168.1.100", "src_port": 12348, "dst_port": 445, "protocol": "TCP", "protocol_num": 6, "packet_size": 1460, "action": "LOG", "interface": "eth0", "flow_hash": "e9f0a1b2"} +{"timestamp": 1732834829, "timestamp_iso": "2024-11-29T10:00:29.000Z", "src_ip": "47.254.33.187", "dst_ip": "192.168.1.100", "src_port": 12349, "dst_port": 445, "protocol": "TCP", "protocol_num": 6, "packet_size": 1460, "action": "LOG", "interface": "eth0", "flow_hash": "f0a1b2c3"} +{"timestamp": 1732834830, "timestamp_iso": "2024-11-29T10:00:30.000Z", "src_ip": "185.220.101.142", "dst_ip": "192.168.1.100", "src_port": 9050, "dst_port": 22, "protocol": "TCP", "protocol_num": 6, "packet_size": 52, "action": "LOG", "interface": "eth0", "flow_hash": "a1b2c3d4"} +{"timestamp": 1732834831, "timestamp_iso": "2024-11-29T10:00:31.000Z", "src_ip": "185.220.101.142", "dst_ip": "192.168.1.100", "src_port": 9051, "dst_port": 22, "protocol": "TCP", "protocol_num": 6, "packet_size": 52, "action": "LOG", "interface": "eth0", "flow_hash": "b2c3d4e5"} +{"timestamp": 1732834832, "timestamp_iso": "2024-11-29T10:00:32.000Z", "src_ip": "185.220.101.142", "dst_ip": "192.168.1.100", "src_port": 9052, "dst_port": 22, "protocol": "TCP", "protocol_num": 6, "packet_size": 52, "action": "LOG", "interface": "eth0", "flow_hash": "c3d4e5f6"} +{"timestamp": 1732834833, "timestamp_iso": "2024-11-29T10:00:33.000Z", "src_ip": "185.220.101.142", "dst_ip": "192.168.1.100", "src_port": 9053, "dst_port": 22, "protocol": "TCP", "protocol_num": 6, "packet_size": 52, "action": "LOG", "interface": "eth0", "flow_hash": "d4e5f6a7"} +{"timestamp": 1732834834, "timestamp_iso": "2024-11-29T10:00:34.000Z", "src_ip": "185.220.101.142", "dst_ip": "192.168.1.100", "src_port": 9054, "dst_port": 22, "protocol": "TCP", "protocol_num": 6, "packet_size": 52, "action": "LOG", "interface": "eth0", "flow_hash": "e5f6a7b8"} +{"timestamp": 1732834835, "timestamp_iso": "2024-11-29T10:00:35.000Z", "src_ip": "94.102.49.190", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "ICMP", "protocol_num": 1, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "f6a7b8c9"} +{"timestamp": 1732834836, "timestamp_iso": "2024-11-29T10:00:36.000Z", "src_ip": "94.102.49.190", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "ICMP", "protocol_num": 1, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "a7b8c9d0"} +{"timestamp": 1732834837, "timestamp_iso": "2024-11-29T10:00:37.000Z", "src_ip": "94.102.49.190", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "ICMP", "protocol_num": 1, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "b8c9d0e1"} +{"timestamp": 1732834838, "timestamp_iso": "2024-11-29T10:00:38.000Z", "src_ip": "94.102.49.190", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "ICMP", "protocol_num": 1, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c9d0e1f2"} +{"timestamp": 1732834839, "timestamp_iso": "2024-11-29T10:00:39.000Z", "src_ip": "94.102.49.190", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "ICMP", "protocol_num": 1, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "d0e1f2a3"} +{"timestamp": 1732834900, "timestamp_iso": "2024-11-29T10:01:40.000Z", "src_ip": "141.98.80.137", "dst_ip": "192.168.1.100", "src_port": 54321, "dst_port": 3389, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "DROP", "interface": "eth0", "flow_hash": "e1f2a3b4"} +{"timestamp": 1732834901, "timestamp_iso": "2024-11-29T10:01:41.000Z", "src_ip": "141.98.80.137", "dst_ip": "192.168.1.100", "src_port": 54322, "dst_port": 3389, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "DROP", "interface": "eth0", "flow_hash": "f2a3b4c5"} +{"timestamp": 1732834902, "timestamp_iso": "2024-11-29T10:01:42.000Z", "src_ip": "141.98.80.137", "dst_ip": "192.168.1.100", "src_port": 54323, "dst_port": 3389, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "DROP", "interface": "eth0", "flow_hash": "a3b4c5d6"} +{"timestamp": 1732834903, "timestamp_iso": "2024-11-29T10:01:43.000Z", "src_ip": "141.98.80.137", "dst_ip": "192.168.1.100", "src_port": 54324, "dst_port": 3389, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "DROP", "interface": "eth0", "flow_hash": "b4c5d6e7"} +{"timestamp": 1732834904, "timestamp_iso": "2024-11-29T10:01:44.000Z", "src_ip": "141.98.80.137", "dst_ip": "192.168.1.100", "src_port": 54325, "dst_port": 3389, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "DROP", "interface": "eth0", "flow_hash": "c5d6e7f8"} +{"timestamp": 1732834905, "timestamp_iso": "2024-11-29T10:01:45.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 2048, "action": "LOG", "interface": "eth0", "flow_hash": "d6e7f8a9"} +{"timestamp": 1732834906, "timestamp_iso": "2024-11-29T10:01:46.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 12346, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 2048, "action": "LOG", "interface": "eth0", "flow_hash": "e7f8a9b0"} +{"timestamp": 1732834907, "timestamp_iso": "2024-11-29T10:01:47.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 12347, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 2048, "action": "LOG", "interface": "eth0", "flow_hash": "f8a9b0c1"} +{"timestamp": 1732834908, "timestamp_iso": "2024-11-29T10:01:48.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 12348, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 2048, "action": "LOG", "interface": "eth0", "flow_hash": "a9b0c1d2"} +{"timestamp": 1732834909, "timestamp_iso": "2024-11-29T10:01:49.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 12349, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 2048, "action": "LOG", "interface": "eth0", "flow_hash": "b0c1d2e3"} +{"timestamp": 1732834910, "timestamp_iso": "2024-11-29T10:01:50.000Z", "src_ip": "111.230.56.78", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "Unknown", "protocol_num": 47, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "c1d2e3f4"} +{"timestamp": 1732834911, "timestamp_iso": "2024-11-29T10:01:51.000Z", "src_ip": "111.230.56.78", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "Unknown", "protocol_num": 47, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "d2e3f4a5"} +{"timestamp": 1732834912, "timestamp_iso": "2024-11-29T10:01:52.000Z", "src_ip": "111.230.56.78", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "Unknown", "protocol_num": 47, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "e3f4a5b6"} \ No newline at end of file diff --git a/traffic-monitor/examples/macos-demo.rs b/traffic-monitor/examples/macos-demo.rs new file mode 100644 index 00000000..80b737c6 --- /dev/null +++ b/traffic-monitor/examples/macos-demo.rs @@ -0,0 +1,116 @@ +use std::{ + net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}, + thread, + time::{Duration, Instant}, +}; +use traffic_monitor::{ + config::TrafficMonitorConfig, + event_handler::{EventHandler, TrafficEvent}, + ip_utils::{ip_in_cidr, parse_cidr}, +}; + +/// Demo that simulates the traffic monitor functionality on macOS +/// This shows how the traffic filtering logic works without requiring XDP +fn main() -> Result<(), Box> { + println!("šŸš€ Traffic Monitor Demo for macOS"); + println!("This simulates the eBPF traffic filtering logic without requiring Linux XDP\n"); + + // Load configuration + let config = TrafficMonitorConfig::default(); + println!("šŸ“‹ Loaded configuration with {} permitted CIDR ranges:", config.permitted_cidrs.len()); + for (i, cidr) in config.permitted_cidrs.iter().enumerate() { + println!(" {}. {}", i + 1, cidr); + } + println!(); + + // Parse CIDR ranges + let mut permitted_ranges = Vec::new(); + for cidr_str in &config.permitted_cidrs { + if let Ok((network, prefix)) = parse_cidr(cidr_str) { + permitted_ranges.push((network, prefix, cidr_str.clone())); + println!("āœ… Parsed CIDR: {} -> network={}, prefix={}", cidr_str, network, prefix); + } else { + println!("āŒ Failed to parse CIDR: {}", cidr_str); + } + } + println!(); + + // Initialize event handler + let mut event_handler = EventHandler::new(); + + // Simulate various IP addresses and show how they would be handled + let test_ips = vec![ + ("127.0.0.1", "Localhost"), + ("192.168.1.100", "Your local network"), + ("10.0.0.50", "Private Class A"), + ("172.16.0.10", "Private Class B"), + ("8.8.8.8", "Google DNS (PUBLIC)"), + ("1.1.1.1", "Cloudflare DNS (PUBLIC)"), + ("52.85.83.228", "Amazon AWS (PUBLIC)"), + ("140.82.113.4", "GitHub (PUBLIC)"), + ("192.168.1.242", "Your current IP"), + ]; + + println!("šŸ” Testing IP addresses against permitted ranges:\n"); + + for (ip_str, description) in &test_ips { + let ip: Ipv4Addr = ip_str.parse().unwrap(); + let mut is_permitted = false; + let mut matched_cidr = String::new(); + + // Check against all CIDR ranges + for (network, prefix, cidr_str) in &permitted_ranges { + if ip_in_cidr(ip, *network, *prefix) { + is_permitted = true; + matched_cidr = cidr_str.clone(); + break; + } + } + + let status = if is_permitted { "āœ… PERMITTED" } else { "🚫 NOT PERMITTED" }; + let match_info = if is_permitted { + format!(" (matches {})", matched_cidr) + } else { + String::new() + }; + + println!(" {} - {} - {}{}", ip_str, description, status, match_info); + + // If not permitted, simulate logging the event + if !is_permitted { + let event = TrafficEvent { + src_ip: u32::from(ip).to_be(), + dst_ip: u32::from(Ipv4Addr::new(192, 168, 1, 242)).to_be(), // Your IP + src_port: 443, + dst_port: 12345, + protocol: 6, // TCP + packet_size: 1500, + action: 0, // Log only (would be 1 for drop) + }; + event_handler.handle_event(event); + } + } + + println!("\nšŸ“Š Statistics Summary:"); + let stats = event_handler.get_stats(); + if stats.is_empty() { + println!(" No non-permitted traffic detected"); + } else { + for (ip_be, ip_stats) in stats { + let ip = Ipv4Addr::from(u32::from_be(*ip_be)); + println!(" {} - {} packets, {} bytes", ip, ip_stats.count, ip_stats.total_bytes); + } + } + + println!("\nšŸ–„ļø On a Linux system, this would:"); + println!(" 1. Load the eBPF program at the XDP layer"); + println!(" 2. Attach to your WiFi interface (en0)"); + println!(" 3. Process packets in real-time at line speed"); + println!(" 4. Log non-permitted traffic to userspace via ring buffer"); + println!(" 5. Optionally drop packets based on configuration"); + + println!("\n🐧 To test on Linux:"); + println!(" sudo ./target/release/traffic-monitor -i wlan0 -c configs/default.json"); + + Ok(()) +} \ No newline at end of file diff --git a/traffic-monitor/examples/sample_traffic.csv b/traffic-monitor/examples/sample_traffic.csv new file mode 100644 index 00000000..c7bf166b --- /dev/null +++ b/traffic-monitor/examples/sample_traffic.csv @@ -0,0 +1,11 @@ +timestamp,timestamp_iso,src_ip,dst_ip,src_port,dst_port,protocol,protocol_num,packet_size,action,interface,flow_hash +1732834800,2024-11-29T10:00:00.000Z,8.8.8.8,192.168.1.100,53,12345,UDP,17,128,LOG,eth0,a1b2c3d4 +1732834801,2024-11-29T10:00:01.000Z,1.1.1.1,192.168.1.100,443,54321,TCP,6,1500,DROP,eth0,b2c3d4e5 +1732834802,2024-11-29T10:00:02.000Z,203.0.113.5,192.168.1.100,80,8080,TCP,6,64,LOG,eth0,c3d4e5f6 +1732834803,2024-11-29T10:00:03.000Z,203.0.113.5,192.168.1.100,22,8080,TCP,6,64,LOG,eth0,d4e5f6a7 +1732834804,2024-11-29T10:00:04.000Z,203.0.113.5,192.168.1.100,23,8080,TCP,6,64,LOG,eth0,e5f6a7b8 +1732834805,2024-11-29T10:00:05.000Z,203.0.113.5,192.168.1.100,25,8080,TCP,6,64,LOG,eth0,f6a7b8c9 +1732834806,2024-11-29T10:00:06.000Z,203.0.113.5,192.168.1.100,53,8080,TCP,6,64,LOG,eth0,a7b8c9d0 +1732834807,2024-11-29T10:00:07.000Z,203.0.113.5,192.168.1.100,79,8080,TCP,6,64,LOG,eth0,b8c9d0e1 +1732834808,2024-11-29T10:00:08.000Z,203.0.113.5,192.168.1.100,135,8080,TCP,6,64,LOG,eth0,c9d0e1f2 +1732834809,2024-11-29T10:00:09.000Z,203.0.113.5,192.168.1.100,139,8080,TCP,6,64,LOG,eth0,d0e1f2a3 \ No newline at end of file diff --git a/traffic-monitor/examples/sample_traffic.jsonl b/traffic-monitor/examples/sample_traffic.jsonl new file mode 100644 index 00000000..0d013902 --- /dev/null +++ b/traffic-monitor/examples/sample_traffic.jsonl @@ -0,0 +1,10 @@ +{"timestamp": 1732834800, "timestamp_iso": "2024-11-29T00:00:00.000Z", "src_ip": "8.8.8.8", "dst_ip": "192.168.1.100", "src_port": 53, "dst_port": 12345, "protocol": "UDP", "protocol_num": 17, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a1b2c3d4"} +{"timestamp": 1732834801, "timestamp_iso": "2024-11-29T00:00:01.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 443, "dst_port": 54321, "protocol": "TCP", "protocol_num": 6, "packet_size": 1500, "action": "DROP", "interface": "eth0", "flow_hash": "b2c3d4e5"} +{"timestamp": 1732834802, "timestamp_iso": "2024-11-29T00:00:02.000Z", "src_ip": "8.8.8.8", "dst_ip": "192.168.1.101", "src_port": 53, "dst_port": 12346, "protocol": "UDP", "protocol_num": 17, "packet_size": 256, "action": "LOG", "interface": "eth0", "flow_hash": "c3d4e5f6"} +{"timestamp": 1732834803, "timestamp_iso": "2024-11-29T00:00:03.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 80, "dst_port": 54322, "protocol": "TCP", "protocol_num": 6, "packet_size": 1024, "action": "LOG", "interface": "eth0", "flow_hash": "d4e5f6a7"} +{"timestamp": 1732834804, "timestamp_iso": "2024-11-29T00:00:04.000Z", "src_ip": "8.8.4.4", "dst_ip": "192.168.1.102", "src_port": 53, "dst_port": 12347, "protocol": "UDP", "protocol_num": 17, "packet_size": 512, "action": "LOG", "interface": "wlan0", "flow_hash": "e5f6a7b8"} +{"timestamp": 1732834805, "timestamp_iso": "2024-11-29T00:00:05.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 22, "dst_port": 54323, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "DROP", "interface": "eth0", "flow_hash": "f6a7b8c9"} +{"timestamp": 1732834806, "timestamp_iso": "2024-11-29T00:00:06.000Z", "src_ip": "8.8.8.8", "dst_ip": "192.168.1.103", "src_port": 53, "dst_port": 12348, "protocol": "UDP", "protocol_num": 17, "packet_size": 320, "action": "LOG", "interface": "eth0", "flow_hash": "a7b8c9d0"} +{"timestamp": 1732834807, "timestamp_iso": "2024-11-29T00:00:07.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 443, "dst_port": 54324, "protocol": "TCP", "protocol_num": 6, "packet_size": 1200, "action": "LOG", "interface": "eth0", "flow_hash": "b8c9d0e1"} +{"timestamp": 1732834808, "timestamp_iso": "2024-11-29T00:00:08.000Z", "src_ip": "8.8.4.4", "dst_ip": "192.168.1.104", "src_port": 53, "dst_port": 12349, "protocol": "UDP", "protocol_num": 17, "packet_size": 128, "action": "LOG", "interface": "wlan0", "flow_hash": "c9d0e1f2"} +{"timestamp": 1732834809, "timestamp_iso": "2024-11-29T00:00:09.000Z", "src_ip": "1.1.1.1", "dst_ip": "192.168.1.100", "src_port": 25, "dst_port": 54325, "protocol": "TCP", "protocol_num": 6, "packet_size": 800, "action": "DROP", "interface": "eth0", "flow_hash": "d0e1f2a3"} \ No newline at end of file diff --git a/traffic-monitor/examples/standalone-demo.rs b/traffic-monitor/examples/standalone-demo.rs new file mode 100644 index 00000000..5e5e82ab --- /dev/null +++ b/traffic-monitor/examples/standalone-demo.rs @@ -0,0 +1,290 @@ +use std::{ + collections::HashMap, + net::Ipv4Addr, + time::Instant, +}; + +/// Standalone demo that shows the traffic filtering logic without eBPF dependencies +/// This runs on any platform and demonstrates how the IP filtering would work + +// CIDR range structure +#[derive(Debug, Clone)] +struct CidrRange { + network: Ipv4Addr, + prefix_len: u8, +} + +impl CidrRange { + fn new(cidr_str: &str) -> Result { + let parts: Vec<&str> = cidr_str.split('/').collect(); + if parts.len() != 2 { + return Err(format!("Invalid CIDR format: {}", cidr_str)); + } + + let ip: Ipv4Addr = parts[0].parse() + .map_err(|_| format!("Invalid IP address: {}", parts[0]))?; + + let prefix_len: u8 = parts[1].parse() + .map_err(|_| format!("Invalid prefix length: {}", parts[1]))?; + + if prefix_len > 32 { + return Err(format!("Prefix length must be 0-32, got: {}", prefix_len)); + } + + // Calculate the network address + let ip_u32 = u32::from(ip); + let mask = if prefix_len == 0 { + 0 + } else { + !((1u32 << (32 - prefix_len)) - 1) + }; + let network_u32 = ip_u32 & mask; + let network_ip = Ipv4Addr::from(network_u32); + + Ok(CidrRange { + network: network_ip, + prefix_len, + }) + } + + fn contains(&self, ip: Ipv4Addr) -> bool { + if self.prefix_len == 0 { + return true; // 0.0.0.0/0 matches everything + } + if self.prefix_len > 32 { + return false; + } + + let ip_u32 = u32::from(ip); + let network_u32 = u32::from(self.network); + + let mask = if self.prefix_len == 32 { + 0xFFFFFFFF + } else { + !((1u32 << (32 - self.prefix_len)) - 1) + }; + + (ip_u32 & mask) == (network_u32 & mask) + } +} + +// Traffic event structure (mirrors eBPF version) +#[derive(Debug, Clone)] +struct TrafficEvent { + src_ip: Ipv4Addr, + dst_ip: Ipv4Addr, + src_port: u16, + dst_port: u16, + protocol: &'static str, + packet_size: u16, + action: &'static str, +} + +// Traffic monitor configuration +struct TrafficMonitor { + permitted_cidrs: Vec, + drop_packets: bool, + stats: HashMap, // (packet_count, total_bytes) +} + +impl TrafficMonitor { + fn new(cidr_strings: Vec<&str>, drop_packets: bool) -> Result { + let mut permitted_cidrs = Vec::new(); + for cidr_str in cidr_strings { + permitted_cidrs.push(CidrRange::new(cidr_str)?); + } + + Ok(TrafficMonitor { + permitted_cidrs, + drop_packets, + stats: HashMap::new(), + }) + } + + fn is_permitted(&self, ip: Ipv4Addr) -> bool { + for cidr in &self.permitted_cidrs { + if cidr.contains(ip) { + return true; + } + } + false + } + + fn process_packet(&mut self, event: TrafficEvent) -> &'static str { + if self.is_permitted(event.src_ip) { + "ALLOWED" + } else { + // Update statistics + let entry = self.stats.entry(event.src_ip).or_insert((0, 0)); + entry.0 += 1; // packet count + entry.1 += event.packet_size as u64; // total bytes + + let action = if self.drop_packets { "DROPPED" } else { "LOGGED" }; + + println!( + "[{}] Non-permitted traffic: {}:{} -> {}:{} (proto: {}, size: {} bytes)", + action, event.src_ip, event.src_port, event.dst_ip, event.dst_port, + event.protocol, event.packet_size + ); + + action + } + } + + fn print_stats(&self) { + if self.stats.is_empty() { + println!("šŸ“Š No non-permitted traffic detected"); + return; + } + + println!("\nšŸ“Š Non-permitted Traffic Statistics:"); + println!("===================================="); + + let mut sorted: Vec<_> = self.stats.iter().collect(); + sorted.sort_by(|a, b| b.1.0.cmp(&a.1.0)); // Sort by packet count + + for (ip, (packets, bytes)) in sorted { + println!(" {} - {} packets, {} bytes", ip, packets, bytes); + } + + let total_packets: u64 = self.stats.values().map(|(p, _)| p).sum(); + let total_bytes: u64 = self.stats.values().map(|(_, b)| b).sum(); + println!(" Total: {} packets, {} bytes from {} unique IPs", + total_packets, total_bytes, self.stats.len()); + } +} + +fn main() -> Result<(), String> { + println!("šŸš€ Traffic Monitor - Standalone Demo"); + println!("=====================================\n"); + + // Configuration - default private networks + let permitted_cidrs = vec![ + "127.0.0.0/8", // Localhost + "10.0.0.0/8", // Private Class A + "172.16.0.0/12", // Private Class B + "192.168.0.0/16", // Private Class C + ]; + + println!("šŸ“‹ Configured permitted CIDR ranges:"); + for (i, cidr) in permitted_cidrs.iter().enumerate() { + println!(" {}. {}", i + 1, cidr); + } + println!(); + + // Create traffic monitor + let mut monitor = TrafficMonitor::new(permitted_cidrs, false)?; + + // Simulate various traffic scenarios + let test_packets = vec![ + TrafficEvent { + src_ip: "127.0.0.1".parse().unwrap(), + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 12345, + dst_port: 80, + protocol: "TCP", + packet_size: 1500, + action: "TEST", + }, + TrafficEvent { + src_ip: "192.168.1.100".parse().unwrap(), + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 22, + dst_port: 54321, + protocol: "TCP", + packet_size: 64, + action: "TEST", + }, + TrafficEvent { + src_ip: "10.0.0.50".parse().unwrap(), + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 443, + dst_port: 12345, + protocol: "TCP", + packet_size: 1200, + action: "TEST", + }, + TrafficEvent { + src_ip: "8.8.8.8".parse().unwrap(), // Google DNS - NOT permitted + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 53, + dst_port: 32768, + protocol: "UDP", + packet_size: 128, + action: "TEST", + }, + TrafficEvent { + src_ip: "1.1.1.1".parse().unwrap(), // Cloudflare DNS - NOT permitted + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 53, + dst_port: 32769, + protocol: "UDP", + packet_size: 256, + action: "TEST", + }, + TrafficEvent { + src_ip: "52.85.83.228".parse().unwrap(), // Amazon AWS - NOT permitted + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 443, + dst_port: 12346, + protocol: "TCP", + packet_size: 1500, + action: "TEST", + }, + TrafficEvent { + src_ip: "140.82.113.4".parse().unwrap(), // GitHub - NOT permitted + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 22, + dst_port: 12347, + protocol: "TCP", + packet_size: 800, + action: "TEST", + }, + TrafficEvent { + src_ip: "172.16.0.10".parse().unwrap(), // Private Class B - permitted + dst_ip: "192.168.1.242".parse().unwrap(), + src_port: 8080, + dst_port: 12348, + protocol: "TCP", + packet_size: 500, + action: "TEST", + }, + ]; + + println!("šŸ” Processing simulated traffic packets:\n"); + + for (i, packet) in test_packets.iter().enumerate() { + let action = monitor.process_packet(packet.clone()); + + if action == "ALLOWED" { + println!("[ALLOWED] Permitted traffic: {}:{} -> {}:{} (proto: {}, size: {} bytes)", + packet.src_ip, packet.src_port, packet.dst_ip, packet.dst_port, + packet.protocol, packet.packet_size); + } + + // Add some variety - simulate multiple packets from same IPs + if i == 3 || i == 4 { // Repeat Google DNS and Cloudflare packets + for _ in 0..3 { + let mut repeat_packet = packet.clone(); + repeat_packet.packet_size += 50; // Vary packet size + monitor.process_packet(repeat_packet); + } + } + } + + monitor.print_stats(); + + println!("\nšŸ–„ļø On a Linux system with this traffic monitor:"); + println!("1. The eBPF program would run at the XDP layer on your WiFi interface"); + println!("2. It would process packets at line speed (millions of packets per second)"); + println!("3. Only non-permitted traffic would be sent to userspace for logging"); + println!("4. Permitted traffic would pass through with minimal overhead"); + println!("5. With --drop-packets, non-permitted traffic would be dropped in the kernel"); + + println!("\n🐧 To run the full version on Linux:"); + println!("sudo ./target/release/traffic-monitor -i en0 -c configs/default.json"); + + println!("\n✨ Demo completed successfully!"); + + Ok(()) +} \ No newline at end of file diff --git a/traffic-monitor/examples/test-traffic.rs b/traffic-monitor/examples/test-traffic.rs new file mode 100644 index 00000000..b3d3ddd2 --- /dev/null +++ b/traffic-monitor/examples/test-traffic.rs @@ -0,0 +1,62 @@ +use std::{ + net::{SocketAddr, UdpSocket}, + thread, + time::Duration, +}; + +/// Simple traffic generator for testing the traffic monitor +/// This generates UDP traffic from various source addresses to test filtering +fn main() -> Result<(), Box> { + println!("Traffic generator starting..."); + + // Test addresses - some permitted (localhost, private), some not + let test_addresses = vec![ + ("127.0.0.1", true), // Localhost - should be permitted + ("192.168.1.100", true), // Private - should be permitted + ("10.0.0.50", true), // Private - should be permitted + ("8.8.8.8", false), // Google DNS - should NOT be permitted + ("1.1.1.1", false), // Cloudflare DNS - should NOT be permitted + ("172.16.0.10", true), // Private - should be permitted + ]; + + let target_port = 8080; + + for (i, (addr, should_be_permitted)) in test_addresses.iter().enumerate() { + println!("Sending test packet from {} (expected: {})", + addr, if *should_be_permitted { "PERMITTED" } else { "NOT PERMITTED" }); + + // This is a simulation - in practice you'd need to actually bind to these addresses + // For testing purposes, we'll just log what we would do + + // Try to bind to the address (this will only work for local addresses) + match format!("{}:0", addr).parse::() { + Ok(bind_addr) => { + if let Ok(socket) = UdpSocket::bind(bind_addr) { + let target = format!("127.0.0.1:{}", target_port); + let message = format!("Test packet {} from {}", i, addr); + + match socket.send_to(message.as_bytes(), &target) { + Ok(_) => println!(" āœ“ Sent packet from {}", addr), + Err(e) => println!(" āœ— Failed to send from {}: {}", addr, e), + } + } else { + println!(" ⚠ Cannot bind to {} (probably not local)", addr); + } + } + Err(e) => { + println!(" āœ— Invalid address {}: {}", addr, e); + } + } + + thread::sleep(Duration::from_millis(500)); + } + + println!("\nTraffic generation complete."); + println!("Note: Only packets from addresses that can be bound locally will actually be sent."); + println!("To fully test external addresses, you would need to:"); + println!("1. Use a network namespace or container"); + println!("2. Configure routing to make external addresses locally routable"); + println!("3. Use raw sockets (requires root privileges)"); + + Ok(()) +} \ No newline at end of file diff --git a/traffic-monitor/examples/threat_traffic.jsonl b/traffic-monitor/examples/threat_traffic.jsonl new file mode 100644 index 00000000..db072558 --- /dev/null +++ b/traffic-monitor/examples/threat_traffic.jsonl @@ -0,0 +1,29 @@ +{"timestamp": 1732834800, "timestamp_iso": "2024-11-29T10:00:00.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 22, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "a1b2c3d4"} +{"timestamp": 1732834801, "timestamp_iso": "2024-11-29T10:00:01.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12346, "dst_port": 23, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "b2c3d4e5"} +{"timestamp": 1732834802, "timestamp_iso": "2024-11-29T10:00:02.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12347, "dst_port": 25, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c3d4e5f6"} +{"timestamp": 1732834803, "timestamp_iso": "2024-11-29T10:00:03.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12348, "dst_port": 53, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "d4e5f6a7"} +{"timestamp": 1732834804, "timestamp_iso": "2024-11-29T10:00:04.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12349, "dst_port": 80, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "e5f6a7b8"} +{"timestamp": 1732834805, "timestamp_iso": "2024-11-29T10:00:05.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12350, "dst_port": 110, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "f6a7b8c9"} +{"timestamp": 1732834806, "timestamp_iso": "2024-11-29T10:00:06.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12351, "dst_port": 135, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "a7b8c9d0"} +{"timestamp": 1732834807, "timestamp_iso": "2024-11-29T10:00:07.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12352, "dst_port": 139, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "b8c9d0e1"} +{"timestamp": 1732834808, "timestamp_iso": "2024-11-29T10:00:08.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12353, "dst_port": 443, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c9d0e1f2"} +{"timestamp": 1732834809, "timestamp_iso": "2024-11-29T10:00:09.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12354, "dst_port": 445, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "d0e1f2a3"} +{"timestamp": 1732834810, "timestamp_iso": "2024-11-29T10:00:10.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12355, "dst_port": 993, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "e1f2a3b4"} +{"timestamp": 1732834811, "timestamp_iso": "2024-11-29T10:00:11.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12356, "dst_port": 995, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "f2a3b4c5"} +{"timestamp": 1732834812, "timestamp_iso": "2024-11-29T10:00:12.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12357, "dst_port": 1433, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "a3b4c5d6"} +{"timestamp": 1732834813, "timestamp_iso": "2024-11-29T10:00:13.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12358, "dst_port": 3306, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "b4c5d6e7"} +{"timestamp": 1732834814, "timestamp_iso": "2024-11-29T10:00:14.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12359, "dst_port": 3389, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "c5d6e7f8"} +{"timestamp": 1732834815, "timestamp_iso": "2024-11-29T10:00:15.000Z", "src_ip": "203.0.113.5", "dst_ip": "192.168.1.100", "src_port": 12360, "dst_port": 5432, "protocol": "TCP", "protocol_num": 6, "packet_size": 64, "action": "LOG", "interface": "eth0", "flow_hash": "d6e7f8a9"} +{"timestamp": 1732834816, "timestamp_iso": "2024-11-29T10:00:16.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 54321, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 65536, "action": "LOG", "interface": "eth0", "flow_hash": "e7f8a9b0"} +{"timestamp": 1732834817, "timestamp_iso": "2024-11-29T10:00:17.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 54322, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 65536, "action": "LOG", "interface": "eth0", "flow_hash": "f8a9b0c1"} +{"timestamp": 1732834818, "timestamp_iso": "2024-11-29T10:00:18.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 54323, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 65536, "action": "LOG", "interface": "eth0", "flow_hash": "a9b0c1d2"} +{"timestamp": 1732834819, "timestamp_iso": "2024-11-29T10:00:19.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 54324, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 65536, "action": "LOG", "interface": "eth0", "flow_hash": "b0c1d2e3"} +{"timestamp": 1732834820, "timestamp_iso": "2024-11-29T10:00:20.000Z", "src_ip": "120.48.85.74", "dst_ip": "192.168.1.100", "src_port": 54325, "dst_port": 9200, "protocol": "TCP", "protocol_num": 6, "packet_size": 65536, "action": "LOG", "interface": "eth0", "flow_hash": "c1d2e3f4"} +{"timestamp": 1732834821, "timestamp_iso": "2024-11-29T10:00:21.000Z", "src_ip": "111.230.56.78", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "GRE", "protocol_num": 47, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "d2e3f4a5"} +{"timestamp": 1732834822, "timestamp_iso": "2024-11-29T10:00:22.000Z", "src_ip": "111.230.56.78", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "ESP", "protocol_num": 50, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "e3f4a5b6"} +{"timestamp": 1732834823, "timestamp_iso": "2024-11-29T10:00:23.000Z", "src_ip": "111.230.56.78", "dst_ip": "192.168.1.100", "src_port": 0, "dst_port": 0, "protocol": "AH", "protocol_num": 51, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "f4a5b6c7"} +{"timestamp": 1732834824, "timestamp_iso": "2024-11-29T10:00:24.000Z", "src_ip": "185.220.101.5", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 80, "protocol": "TCP", "protocol_num": 6, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a5b6c7d8"} +{"timestamp": 1732834825, "timestamp_iso": "2024-11-29T10:00:25.000Z", "src_ip": "185.220.101.5", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 80, "protocol": "TCP", "protocol_num": 6, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a5b6c7d8"} +{"timestamp": 1732834826, "timestamp_iso": "2024-11-29T10:00:26.000Z", "src_ip": "185.220.101.5", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 80, "protocol": "TCP", "protocol_num": 6, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a5b6c7d8"} +{"timestamp": 1732834827, "timestamp_iso": "2024-11-29T10:00:27.000Z", "src_ip": "185.220.101.5", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 80, "protocol": "TCP", "protocol_num": 6, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a5b6c7d8"} +{"timestamp": 1732834828, "timestamp_iso": "2024-11-29T10:00:28.000Z", "src_ip": "185.220.101.5", "dst_ip": "192.168.1.100", "src_port": 12345, "dst_port": 80, "protocol": "TCP", "protocol_num": 6, "packet_size": 128, "action": "LOG", "interface": "eth0", "flow_hash": "a5b6c7d8"} \ No newline at end of file