import json import os from config_utils import collect_layout_tokens _EXCLUDE_PREFIXES = ('lo', 'wg', 'docker', 'br-', 'veth', 'tun', 'tap', 'ppp', 'virbr', 'podman', 'vnet', 'macvtap', 'fc-') def get_system_interfaces(): try: return sorted( n for n in os.listdir('/sys/class/net') if not n.startswith(_EXCLUDE_PREFIXES) and os.path.exists(f'/sys/class/net/{n}/device') ) except Exception: return [] def iface_info(iface): base = f'/sys/class/net/{iface}' def rd(path): try: with open(f'{base}/{path}') as f: return f.read().strip() except Exception: return None def int_val(val): try: return int(val) if val else None except ValueError: return None wireless = os.path.isdir(f'{base}/wireless') state = (rd('operstate') or 'unknown').upper() if state == 'UNKNOWN': state = 'UP' carrier_raw = rd('carrier') carrier = (carrier_raw == '1') if carrier_raw is not None else None speed_raw = rd('speed') try: mbps = int(speed_raw) if mbps <= 0: speed = None elif mbps >= 1000 and mbps % 1000 == 0: speed = f'{mbps // 1000} Gbps' else: speed = f'{mbps} Mbps' except (TypeError, ValueError): speed = None mac = rd('address') perm_mac = rd('perm_address') if perm_mac and perm_mac == '00:00:00:00:00:00': perm_mac = None return { 'name': iface, 'wireless': wireless, 'state': state, 'carrier': carrier, 'speed': speed, 'mtu': rd('mtu'), 'min_mtu': int_val(rd('min_mtu')), 'max_mtu': int_val(rd('max_mtu')), 'mac': mac, 'perm_mac': perm_mac, } def collect_tokens(cfg): tokens = collect_layout_tokens(cfg) net = cfg.get('network_interfaces', {}) wan = net.get('wan_interface', '') lan = net.get('lan_interface', '') sys_ifaces = get_system_interfaces() for configured in [wan, lan]: if configured and configured not in sys_ifaces: sys_ifaces.append(configured) sys_ifaces.sort() iface_data = [iface_info(i) for i in sys_ifaces] tokens['GENERAL_WAN_INTERFACE'] = str(wan or '-') tokens['NETWORK_INTERFACE_DATA_JSON'] = json.dumps(iface_data) return tokens