Get detailed activity logs showing discoveries, attacks, and results
()
| 7035 | 'last_seen': current_time, |
| 7036 | 'last_successful_ping': current_time, |
| 7037 | 'failed_ping_count': 0 # New devices start with 0 failures |
| 7038 | } |
| 7039 | # Add to NetKB database as well |
| 7040 | try: |
| 7041 | update_netkb_entry(ip, arp_data.get('hostname', ''), arp_data.get('mac', ''), True) |
| 7042 | except Exception as e: |
| 7043 | logger.debug(f"Could not add new ARP discovery to NetKB for {ip}: {e}") |
| 7044 | |
| 7045 | # Prepare aggregated counts from persisted data using PROPER 5-ping rule |
| 7046 | aggregated_host_count = 0 |
| 7047 | aggregated_active_count = 0 |
| 7048 | aggregated_inactive_count = 0 |
| 7049 | aggregated_port_count = 0 |
| 7050 | |
| 7051 | for ip, data in existing_data.items(): |
| 7052 | aggregated_host_count += 1 |
| 7053 | |
| 7054 | # Apply the PROPER 5-ping rule for counting active targets |
| 7055 | failed_ping_count = data.get('failed_ping_count', 0) |
| 7056 | |
| 7057 | # TARGET IS ACTIVE IF: |
| 7058 | # 1. It has fewer than MAX_FAILED_PINGS consecutive failures, OR |
| 7059 | # 2. It's marked as explicitly alive (from ARP response) |
| 7060 | is_explicitly_alive = data.get('alive', True) |
| 7061 | has_not_exceeded_failure_limit = failed_ping_count < MAX_FAILED_PINGS |
| 7062 | |
| 7063 | # A target is active if it hasn't exceeded the failure limit OR if it's currently responding |
| 7064 | is_target_active = has_not_exceeded_failure_limit or is_explicitly_alive |
| 7065 | |
| 7066 | if is_target_active: |
| 7067 | aggregated_active_count += 1 |
| 7068 | aggregated_port_count += sum(1 for port in data['ports'] if port) |
| 7069 | # Only log every 10th device or devices approaching failure threshold |
| 7070 | if aggregated_active_count % 10 == 1 or failed_ping_count >= MAX_FAILED_PINGS - 2: |
| 7071 | logger.debug(f"[15-PING RULE] {ip}: ACTIVE (failures={failed_ping_count}/{MAX_FAILED_PINGS}, alive={is_explicitly_alive})") |
| 7072 | else: |
| 7073 | aggregated_inactive_count += 1 |
| 7074 | logger.info(f"[15-PING RULE] {ip}: INACTIVE (failures={failed_ping_count}/{MAX_FAILED_PINGS}, alive={is_explicitly_alive})") |
| 7075 | |
| 7076 | # Write updated data to WiFi-specific file |
| 7077 | try: |
| 7078 | # Count ports before writing for debugging |
| 7079 | total_ports_to_write = sum(len(data['ports']) for data in existing_data.values()) |
| 7080 | hosts_with_many_ports = sum(1 for data in existing_data.values() if len(data['ports']) > 10) |
| 7081 | |
| 7082 | logger.debug(f"[WIFI DATA WRITE] Writing {len(existing_data)} hosts with {total_ports_to_write} total ports ({hosts_with_many_ports} hosts with >10 ports)") |
| 7083 | |
| 7084 | with open(wifi_network_file, 'w', newline='', encoding='utf-8') as f: |
| 7085 | writer = csv.writer(f) |
| 7086 | writer.writerow(['IP', 'Hostname', 'Alive', 'MAC', 'Ports', 'LastSeen', 'FailedPingCount', 'LastSuccessfulPing', 'LastPingAttempt']) |
| 7087 | |
| 7088 | for ip, data in existing_data.items(): |
| 7089 | def port_sort_key(value): |
| 7090 | if value.isdigit(): |
| 7091 | return int(value) |
| 7092 | try: |
| 7093 | match = re.match(r"^(\d+)", value) |
| 7094 | if match: |