def fw_events(file, filter_ip, filter_type, clients_dir, net_file, limit): """ Format firewall drop events with dedup, counts, and service annotation. Output per line: ts|client|dest_ip|dest_port|proto|service_name|count """ import glob from datetime import datetime proto_map = {1: 'icmp', 6: 'tcp', 17: 'udp'} # Build ip->name map ip_to_name = {} for conf in glob.glob(f"{clients_dir}/*.conf"): name = os.path.basename(conf).replace('.conf', '') try: with open(conf) as f: for line in f: if line.startswith('Address'): ip = line.split('=')[1].strip().split('/')[0] ip_to_name[ip] = name except Exception: pass # Load net services for reverse lookup — independent of rest of function net_data = {} if net_file and os.path.exists(net_file): try: with open(net_file) as f: net_data = json.load(f) except Exception: pass def reverse_lookup(dest_ip, dest_port, proto): for svc_name, svc in net_data.items(): if not isinstance(svc, dict): continue if svc.get('ip', '') != dest_ip: continue ports = svc.get('ports', {}) if dest_port: for port_name, port_def in ports.items(): if not isinstance(port_def, dict): continue if (str(port_def.get('port', '')) == str(dest_port) and port_def.get('proto', 'tcp') == proto): return f"{svc_name}:{port_name}" return svc_name return svc_name return '' # Parse and first-pass dedup (within time window per key) events = [] last_seen = {} try: with open(file) as f: for line in f: try: e = json.loads(line.strip()) src = e.get('src_ip', '') if not src: continue if filter_ip and src != filter_ip: continue proto_num = int(e.get('ip.protocol', 0)) proto = proto_map.get(proto_num, str(proto_num)) dst = e.get('dest_ip', '') port = str(e.get('dest_port', '')) key = (src, dst, port, proto_num) ts_str = e.get('timestamp', '') try: ts = datetime.fromisoformat(ts_str).timestamp() except Exception: ts = 0 windows = {1: 5, 6: 30, 17: 10} window = windows.get(proto_num, 10) if key in last_seen and (ts - last_seen[key]) < window: continue def wg_events(file, filter_client, filter_type, limit): """ Format WireGuard events with dedup and counts. Output per line: ts|client|endpoint|event|count """ from datetime import datetime events = [] try: with open(file) as f: for line in f: try: e = json.loads(line.strip()) client = e.get('client', '') if not client: continue if filter_client and client != filter_client: continue if filter_type and not client.startswith(filter_type + '-'): continue events.append(e) except Exception: pass except Exception: pass # Dedup consecutive same client+event+endpoint within 60s deduped = [] counts = [] for e in events: ts_str = e.get('timestamp', '') try: ts = datetime.fromisoformat(ts_str).timestamp() except Exception: ts = 0 client = e.get('client', '') event = e.get('event', '') endpoint = e.get('endpoint', '') key = (client, event, endpoint[:15]) if deduped: prev = deduped[-1] prev_ts_str = prev.get('timestamp', '') try: prev_ts = datetime.fromisoformat(prev_ts_str).timestamp() except Exception: prev_ts = 0 prev_key = ( prev.get('client', ''), prev.get('event', ''), prev.get('endpoint', '')[:15] ) if key == prev_key and (ts - prev_ts) < 300: counts[-1] += 1 continue deduped.append(e) counts.append(1) limit = int(limit) if limit else 50