import os import socket import psutil import json import logging import argparse # Globaler Debug-Status _debug_mode = False def set_debug_mode(enabled: bool): """Setzt den globalen Debug-Modus für das Modul.""" global _debug_mode _debug_mode = enabled # Farben für CLI-Ausgabe class LogColors: INFO = "\033[94m" DEBUG = "\033[92m" WARNING = "\033[93m" ERROR = "\033[91m" RESET = "\033[0m" def setup_logging(): """Initialisiert das Logging""" log_file = os.path.expanduser("~/netinf.log") logging.basicConfig( filename=log_file, level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) def log_message(level, message, debug_mode=False): """Loggt Nachrichten mit Farben für die CLI.""" if level == "info": logging.info(message) if debug_mode: print(f"{LogColors.INFO}[INFO]{LogColors.RESET} {message}") elif level == "warning": logging.warning(message) if debug_mode: print(f"{LogColors.WARNING}[WARNING]{LogColors.RESET} {message}") elif level == "error": logging.error(message) if debug_mode: print(f"{LogColors.ERROR}[ERROR]{LogColors.RESET} {message}") def get_network_info(debug=None): """Erfasst Netzwerkinformationen und gibt sie formatiert auf der CLI aus.""" # Nutze den globalen Debug-Modus, wenn nicht explizit angegeben is_debug = _debug_mode if debug is None else debug log_message("info", "Sammle Netzwerkinformationen...", is_debug) network_info = {} try: hostname = socket.gethostname() ip_address = socket.gethostbyname(hostname) network_info["hostname"] = hostname network_info["ip_address"] = ip_address log_message("info", f"Hostname: {hostname}, IP-Adresse: {ip_address}", is_debug) print(f"{LogColors.INFO}Hostname:{LogColors.RESET} {hostname}") print(f"{LogColors.INFO}IP-Adresse:{LogColors.RESET} {ip_address}") print(f"{LogColors.INFO}Netzwerkschnittstellen:{LogColors.RESET}") interfaces = {} for interface, addrs in psutil.net_if_addrs().items(): print(f" {interface}:") iface_info = {} for addr in addrs: if addr.family == socket.AF_INET: print(f" IPv4: {addr.address}") iface_info["ipv4"] = addr.address elif addr.family == socket.AF_INET6: print(f" IPv6: {addr.address}") iface_info["ipv6"] = addr.address elif addr.family == psutil.AF_LINK: print(f" MAC: {addr.address}") iface_info["mac"] = addr.address interfaces[interface] = iface_info network_info["interfaces"] = interfaces # Standard-Gateway abrufen try: gateway_info = os.popen("ip route | grep default").read().split()[2] except Exception: gateway_info = "Nicht verfügbar" network_info["gateway"] = gateway_info print(f"{LogColors.INFO}Standard-Gateway:{LogColors.RESET} {gateway_info}") # DNS-Server abrufen dns_servers = [] try: dns_output = os.popen("resolvectl status | grep 'DNS Servers' | awk '{print $3}'").read().split() if not dns_output: dns_output = os.popen("nmcli dev show | grep 'IP4.DNS' | awk '{print $2}'").read().split() if not dns_output: with open("/etc/resolv.conf", "r") as f: for line in f: if line.startswith("nameserver"): dns_servers.append(line.split()[1]) else: dns_servers = dns_output except Exception: dns_servers.append("Nicht verfügbar") network_info["dns_servers"] = dns_servers print(f"{LogColors.INFO}DNS-Server:{LogColors.RESET} {', '.join(dns_servers)}") connections = psutil.net_connections(kind='inet') print(f"{LogColors.INFO}Erfasste Verbindungen ({len(connections)}):{LogColors.RESET}") connection_list = [] for conn in connections[:10]: # Begrenze die Anzahl der ausgegebenen Verbindungen connection_info = { "local_ip": conn.laddr.ip if conn.laddr else "", "local_port": conn.laddr.port if conn.laddr else "", "remote_ip": conn.raddr.ip if conn.raddr else "", "remote_port": conn.raddr.port if conn.raddr else "", "status": conn.status, "type": "TCP" if conn.type == socket.SOCK_STREAM else "UDP" } connection_list.append(connection_info) print( f" {connection_info['type']} " f"{connection_info['local_ip']}:{connection_info['local_port']} -> " f"{connection_info['remote_ip']}:{connection_info['remote_port']} " f"({connection_info['status']})" ) network_info["connections"] = connection_list except Exception as e: log_message("error", f"Fehler beim Erfassen der Netzwerkinformationen: {e}", is_debug) return network_info if __name__ == "__main__": parser = argparse.ArgumentParser(description="Ermittelt Netzwerkinformationen.") parser.add_argument("--debug", action="store_true", help="Aktiviert Debug-Logging auf der CLI.") parser.add_argument("--json", type=str, help="Speichert die Ausgabe in einer JSON-Datei.") args = parser.parse_args() setup_logging() net_info = get_network_info(debug=args.debug) if args.json: try: with open(args.json, "w") as json_file: json.dump(net_info, json_file, indent=4) log_message("info", f"Netzwerk-Infos in JSON gespeichert: {args.json}", args.debug) except Exception as e: log_message("error", f"Fehler beim Speichern der JSON-Datei: {e}", args.debug)