|
10 | 10 | import psutil |
11 | 11 | import requests |
12 | 12 | import scapy.all as scapy |
| 13 | +from scapy.layers.inet import IP |
| 14 | +from scapy.layers.inet6 import IPv6 |
13 | 15 |
|
14 | 16 |
|
15 | 17 | def get_network_interfaces(): |
@@ -55,28 +57,37 @@ def is_allowed(ip): |
55 | 57 | logging.error(f"Invalid IP address: {ip}") |
56 | 58 | return False |
57 | 59 |
|
| 60 | + def process_ip_packet(ip_layer, packet): |
| 61 | + """Handles common processing for both IPv4 and IPv6 packets.""" |
| 62 | + src_ip = ip_layer.src |
| 63 | + dst_ip = ip_layer.dst |
| 64 | + packet_size = len(packet) |
| 65 | + |
| 66 | + # Check traffic involving LOCAL interfaces (sent OR received) |
| 67 | + if src_ip in local_interface_ips: # Traffic SENT by local interface |
| 68 | + if is_allowed(dst_ip): # Destination is allowed |
| 69 | + traffic_stats[dst_ip]["recv"] += packet_size # Count as received by destination (even if sent by us) |
| 70 | + else: |
| 71 | + non_allowlist_traffic[dst_ip] += packet_size |
| 72 | + elif dst_ip in local_interface_ips: # Traffic RECEIVED by local interface |
| 73 | + if is_allowed(src_ip): # Source is allowed |
| 74 | + traffic_stats[src_ip]["sent"] += packet_size # Count as sent by source (even if received by us) |
| 75 | + else: |
| 76 | + non_allowlist_traffic[src_ip] += packet_size |
| 77 | + else: # Traffic between non-local interfaces (not relevant for our monitoring) |
| 78 | + logging.debug(f"Traffic between non-local interfaces received! {src_ip} -> {dst_ip}") |
| 79 | + |
58 | 80 | def packet_handler(packet): |
59 | 81 | """Handle each packet to aggregate traffic statistics.""" |
60 | 82 | nonlocal traffic_stats, non_allowlist_traffic, local_interface_ips |
61 | | - if scapy.IP in packet: |
62 | | - ip_layer = packet[scapy.IP] |
63 | | - src_ip = ip_layer.src |
64 | | - dst_ip = ip_layer.dst |
65 | | - packet_size = len(packet) |
66 | | - |
67 | | - # Check traffic involving LOCAL interfaces (sent OR received) |
68 | | - if src_ip in local_interface_ips: # Traffic SENT by local interface |
69 | | - if is_allowed(dst_ip): # Destination is allowed |
70 | | - traffic_stats[dst_ip]["recv"] += packet_size # Count as received by destination (even if sent by us) |
71 | | - else: |
72 | | - non_allowlist_traffic[dst_ip] += packet_size |
73 | | - elif dst_ip in local_interface_ips: # Traffic RECEIVED by local interface |
74 | | - if is_allowed(src_ip): # Source is allowed |
75 | | - traffic_stats[src_ip]["sent"] += packet_size # Count as sent by source (even if received by us) |
76 | | - else: |
77 | | - non_allowlist_traffic[src_ip] += packet_size |
78 | | - else: # Traffic between non-local interfaces (not relevant for our monitoring) |
79 | | - logging.debug(f"Traffic between non-local interfaces received! {src_ip} -> {dst_ip}") |
| 83 | + if IP in packet: |
| 84 | + ip_layer = packet[IP] |
| 85 | + process_ip_packet(ip_layer, packet) |
| 86 | + elif IPv6 in packet: |
| 87 | + ip_layer = packet[IPv6] |
| 88 | + process_ip_packet(ip_layer, packet) |
| 89 | + else: |
| 90 | + logging.debug(f"Non IP packet received: {packet}") |
80 | 91 |
|
81 | 92 | def get_local_interface_ips(): |
82 | 93 | """Get the IP addresses of the local network interfaces.""" |
|
0 commit comments