#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
网络工具函数模块
提供基础网络诊断能力供 AI 调用
"""

import subprocess
import socket
import platform
import re
import requests
import struct
import random
import time
from concurrent.futures import ThreadPoolExecutor, as_completed


def _parse_ports(ports: str):
    """解析端口字符串，支持范围与常用端口关键字"""
    if not ports:
        return [22, 80, 443, 3389, 8080], None

    port_text = str(ports).strip().lower()

    if "常用" in port_text or "common" in port_text:
        return [21, 22, 23, 25, 53, 80, 110, 143, 443, 465, 587, 993, 995, 3306, 3389], None

    if port_text in {"全端口", "all", "full", "1-65535"}:
        return list(range(1, 1025)), "⚠️ 已自动限制为 1-1024（全端口太慢）。如需全端口，请输入“全端口确认”或“1-65535”。"
    if port_text in {"全端口确认", "all!", "full!", "确认全端口"}:
        return list(range(1, 65536)), "⚠️ 全端口扫描可能耗时较长，请耐心等待。"

    tokens = re.split(r'[,\s]+', port_text)
    port_set = set()
    for token in tokens:
        if not token:
            continue
        if '-' in token:
            parts = token.split('-', 1)
            try:
                start = int(parts[0])
                end = int(parts[1])
            except ValueError:
                continue
            if start <= 0:
                start = 1
            if end > 65535:
                end = 65535
            if start > end:
                start, end = end, start
            for p in range(start, end + 1):
                port_set.add(p)
        else:
            try:
                p = int(token)
            except ValueError:
                continue
            if 1 <= p <= 65535:
                port_set.add(p)

    if not port_set:
        return [], "❌ 无效的端口列表，请使用例如：80,443,1000-1024 或 常用端口/全端口"

    return sorted(port_set), None


def run_ping(host: str, count: int = 4, timeout: int = 1000) -> str:
    """执行 Ping 测试"""
    try:
        if platform.system() == "Windows":
            cmd = f'ping -n {count} -w {timeout} {host}'
        else:
            cmd = f'ping -c {count} -W {timeout//1000} {host}'

        startupinfo = None
        if platform.system() == "Windows":
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE

        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True,
            encoding='gbk' if platform.system() == "Windows" else 'utf-8',
            errors='replace', timeout=30, startupinfo=startupinfo
        )

        output = result.stdout if result.stdout else result.stderr

        if "TTL=" in output or "ttl=" in output:
            lines = output.strip().split('\n')
            stats_lines = [l for l in lines if '丢失' in l or 'loss' in l.lower() or '平均' in l or 'Average' in l]
            summary = '\n'.join(stats_lines[-3:]) if stats_lines else output[-500:]
            return f"✅ Ping {host} 成功\n{summary}"
        else:
            return f"❌ Ping {host} 失败\n{output[:500]}"

    except subprocess.TimeoutExpired:
        return f"⏱️ Ping {host} 超时"
    except Exception as e:
        return f"❌ Ping执行错误: {str(e)}"


def run_tracert(host: str, max_hops: int = 30) -> str:
    """执行路由追踪(增强版:带位置和运营商信息)"""
    try:
        if platform.system() == "Windows":
            cmd = f'tracert -h {max_hops} {host}'
        else:
            cmd = f'traceroute -m {max_hops} {host}'

        startupinfo = None
        if platform.system() == "Windows":
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE

        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True,
            encoding='gbk' if platform.system() == "Windows" else 'utf-8',
            errors='replace', timeout=120, startupinfo=startupinfo
        )

        output = result.stdout if result.stdout else result.stderr
        
        # 增强:解析tracert输出,添加IP位置和运营商信息
        enhanced_output = _enhance_tracert_output(output, host)
        
        return f"🛤️ 路由追踪 {host}:\n{enhanced_output[:5000]}"

    except subprocess.TimeoutExpired:
        return f"⏱️ 路由追踪 {host} 超时"
    except Exception as e:
        return f"❌ 路由追踪错误: {str(e)}"


def _enhance_tracert_output(tracert_output: str, host: str) -> str:
    """增强tracert输出,添加IP位置和运营商信息"""
    try:
        import re
        
        lines = tracert_output.split('\n')
        enhanced_lines = []
        ip_cache = {}  # 缓存IP查询结果,避免重复查询
        
        # IP地址匹配正则
        ip_pattern = re.compile(r'\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b')
        
        for line in lines:
            enhanced_lines.append(line)
            
            # 查找行中的IP地址
            ip_match = ip_pattern.search(line)
            if ip_match:
                ip = ip_match.group(1)
                
                # 跳过无效IP和已查询的IP
                if ip.startswith('0.') or ip.startswith('255.') or ip in ip_cache:
                    if ip in ip_cache and ip_cache[ip]:
                        enhanced_lines.append(ip_cache[ip])
                    continue
                
                # 跳过私有IP和特殊IP
                try:
                    import ipaddress
                    ip_obj = ipaddress.ip_address(ip)
                    if ip_obj.is_private or ip_obj.is_loopback or ip_obj.is_link_local:
                        ip_cache[ip] = None
                        continue
                except:
                    continue
                
                # 查询IP位置和运营商信息
                ip_info = _query_ip_location(ip)
                if ip_info:
                    ip_cache[ip] = ip_info
                    enhanced_lines.append(ip_info)
                else:
                    ip_cache[ip] = None
        
        return '\n'.join(enhanced_lines)
        
    except Exception as e:
        # 如果增强失败,返回原始输出
        return tracert_output


def _query_ip_location(ip: str) -> str:
    """查询IP的位置和运营商信息(快速版)"""
    try:
        import requests
        
        # 使用ipinfo.io API(免费,较快)
        response = requests.get(f"https://ipinfo.io/{ip}/json", timeout=3)
        if response.status_code == 200:
            data = response.json()
            
            # 提取关键信息
            city = data.get('city', '')
            region = data.get('region', '')
            country = data.get('country', '')
            org = data.get('org', '')  # 运营商/组织
            
            # 格式化信息
            location_parts = []
            if country:
                location_parts.append(country)
            if region and region != city:
                location_parts.append(region)
            if city:
                location_parts.append(city)
            
            location_str = ' '.join(location_parts) if location_parts else '未知'
            org_str = org if org else '未知'
            
            return f"      └─ 📍 {location_str} | 🏢 {org_str}"
        
        return None
        
    except requests.exceptions.Timeout:
        # 超时,返回提示
        return "      └─ ⏱️ 查询超时"
    except requests.exceptions.ConnectionError:
        # 连接失败
        return None
    except Exception as e:
        # 其他错误,调试时可以打印
        # print(f"查询IP {ip} 失败: {e}")
        return None


def _pick_port_scan_threads(port_count: int, threads: int | None) -> int:
    """根据端口数量选择线程数，最大1000"""
    if threads is not None:
        try:
            threads = int(threads)
        except Exception:
            threads = None

    if threads is not None:
        return max(1, min(1000, threads))

    if port_count >= 20000:
        return 1000
    if port_count >= 5000:
        return 500
    if port_count >= 1000:
        return 200
    return max(50, min(200, port_count))


def run_port_scan(host: str, ports: str = "22,80,443,3389,8080", timeout: float = 1.0, threads: int | None = None) -> str:
    """执行端口扫描"""
    try:
        port_list, warning = _parse_ports(ports)
        if not port_list:
            return warning or "❌ 无效的端口列表"

        max_workers = _pick_port_scan_threads(len(port_list), threads)

        open_ports = []
        closed_ports = []

        def scan_port(port):
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(timeout)
                result = sock.connect_ex((host, port))
                sock.close()
                return port, result == 0
            except Exception:
                return port, False

        with ThreadPoolExecutor(max_workers=max_workers) as executor:
            futures = {executor.submit(scan_port, port): port for port in port_list}
            for future in as_completed(futures):
                port, is_open = future.result()
                if is_open:
                    open_ports.append(port)
                else:
                    closed_ports.append(port)

        result = f"🔍 端口扫描 {host}:\n"
        if warning:
            result += f"{warning}\n"
        result += f"线程数: {max_workers}\n"
        if open_ports:
            result += f"✅ 开放端口: {', '.join(map(str, sorted(open_ports)))}\n"
        if closed_ports:
            result += f"❌ 关闭端口: {', '.join(map(str, sorted(closed_ports)))}\n"

        return result

    except Exception as e:
        return f"❌ 端口扫描错误: {str(e)}"


def run_dns_query(domain: str, record_type: str = "A") -> str:
    """执行 DNS 查询"""
    try:
        if platform.system() == "Windows":
            cmd = f'nslookup -type={record_type} {domain}'
        else:
            cmd = f'dig {domain} {record_type}'

        startupinfo = None
        if platform.system() == "Windows":
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE

        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True,
            encoding='gbk' if platform.system() == "Windows" else 'utf-8',
            errors='replace', timeout=30, startupinfo=startupinfo
        )

        output = result.stdout if result.stdout else result.stderr
        return f"🔍 DNS查询 {domain} ({record_type}):\n{output[:1500]}"

    except Exception as e:
        return f"❌ DNS查询错误: {str(e)}"


def run_subnet_calc(ip_cidr: str) -> str:
    """计算子网信息"""
    try:
        import ipaddress
        network = ipaddress.ip_network(ip_cidr, strict=False)

        result = f"📊 子网计算 {ip_cidr}:\n"
        result += f"网络地址: {network.network_address}\n"
        result += f"广播地址: {network.broadcast_address}\n"
        result += f"子网掩码: {network.netmask}\n"
        result += f"反掩码: {network.hostmask}\n"
        result += f"可用主机数: {network.num_addresses - 2 if network.num_addresses > 2 else 0}\n"

        hosts = list(network.hosts())
        if hosts:
            result += f"主机范围: {hosts[0]} - {hosts[-1]}\n"
        result += f"CIDR: /{network.prefixlen}\n"

        return result

    except Exception as e:
        return f"❌ 子网计算错误: {str(e)}"


def run_network_info(info_type: str = "all") -> str:
    """查询网络信息"""
    try:
        startupinfo = None
        if platform.system() == "Windows":
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE

        result = subprocess.run(
            'ipconfig /all', shell=True, capture_output=True, text=True,
            encoding='gbk', errors='replace', timeout=30, startupinfo=startupinfo
        )

        output = result.stdout

        if info_type == "all":
            return f"🌐 网络配置信息:\n{output[:3000]}"
        elif info_type == "ip":
            ip_pattern = r'IPv4.*?:\s*(\d+\.\d+\.\d+\.\d+)'
            ips = re.findall(ip_pattern, output)
            return f"🌐 本机IP地址: {', '.join(ips)}"
        elif info_type == "dns":
            dns_pattern = r'DNS.*?:\s*(\d+\.\d+\.\d+\.\d+)'
            dns_servers = re.findall(dns_pattern, output)
            return f"🌐 DNS服务器: {', '.join(dns_servers)}"
        elif info_type == "gateway":
            gw_pattern = r'默认网关.*?:\s*(\d+\.\d+\.\d+\.\d+)'
            gateways = re.findall(gw_pattern, output)
            return f"🌐 默认网关: {', '.join(gateways)}"
        else:
            return f"🌐 网络配置信息:\n{output[:2000]}"

    except Exception as e:
        return f"❌ 网络信息查询错误: {str(e)}"


def run_public_ip() -> str:
    """获取公网IP地址"""
    endpoints = [
        "https://api.ipify.org?format=json",
        "https://ifconfig.me/all.json",
        "https://ipinfo.io/json"
    ]
    for url in endpoints:
        try:
            resp = requests.get(url, timeout=5)
            if resp.status_code != 200:
                continue
            data = resp.json()
            ip = data.get("ip") or data.get("IP") or data.get("address")
            if ip:
                return f"🌍 公网IP: {ip}"
        except Exception:
            continue
    return "❌ 获取公网IP失败，请检查网络或稍后重试"


def run_windows_command(command: str) -> str:
    """执行 Windows 命令"""
    dangerous_keywords = ['format', 'del /s', 'rd /s', 'rmdir /s', 'deltree',
                         'reg delete', 'shutdown', 'taskkill /f']

    for keyword in dangerous_keywords:
        if keyword.lower() in command.lower():
            return f"⛔ 危险命令已阻止: {command}"

    try:
        startupinfo = None
        if platform.system() == "Windows":
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE

        result = subprocess.run(
            command, shell=True, capture_output=True, text=True,
            encoding='gbk', errors='replace', timeout=60, startupinfo=startupinfo
        )

        output = result.stdout if result.stdout else result.stderr

        if output:
            return f"✅ 命令执行完成:\n{output[:2000]}"
        else:
            return f"✅ 命令执行完成（无输出）"

    except subprocess.TimeoutExpired:
        return f"⏱️ 命令执行超时: {command}"
    except Exception as e:
        return f"❌ 命令执行错误: {str(e)}"


def run_speed_test() -> str:
    """执行网速测试"""
    try:
        # 使用华为云测速站点
        test_url = "https://speed.huaweicloud.com/download/test_100MB.bin"
        
        result = "⚡ 网速测试\n"
        result += "=" * 50 + "\n"
        result += "正在测试下载速度...\n\n"
        
        import time
        start_time = time.time()
        
        # 测试延迟
        try:
            ping_result = subprocess.run(
                'ping -n 4 speed.huaweicloud.com', 
                shell=True, capture_output=True, text=True,
                encoding='gbk', errors='replace', timeout=10
            )
            if "平均" in ping_result.stdout or "Average" in ping_result.stdout:
                for line in ping_result.stdout.split('\n'):
                    if '平均' in line or 'Average' in line.lower():
                        result += f"🔍 延迟测试: {line.strip()}\n"
        except:
            result += "⚠️ 延迟测试失败\n"
        
        # 简单下载测试
        try:
            response = requests.get(test_url, timeout=30, stream=True)
            total_size = 0
            chunk_count = 0
            max_chunks = 50  # 限制下载量
            
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    total_size += len(chunk)
                    chunk_count += 1
                    if chunk_count >= max_chunks:
                        break
            
            elapsed = time.time() - start_time
            speed_mbps = (total_size * 8 / 1024 / 1024) / elapsed if elapsed > 0 else 0
            
            result += f"\n📊 测试结果:\n"
            result += f"  下载数据: {total_size / 1024:.2f} KB\n"
            result += f"  耗时: {elapsed:.2f} 秒\n"
            result += f"  下载速度: {speed_mbps:.2f} Mbps\n"
            
        except Exception as e:
            result += f"\n❌ 下载测试失败: {str(e)}\n"
        
        result += "\n💡 提示: 建议使用专业测速网站获得更准确结果\n"
        result += "   推荐: https://www.speedtest.cn/\n"
        
        return result
        
    except Exception as e:
        return f"❌ 网速测试错误: {str(e)}"


def run_ip_info_query(ip: str = "") -> str:
    """查询IP信息（本机或指定IP）"""
    try:
        result = "🌍 IP信息查询\n"
        result += "=" * 50 + "\n\n"
        
        if not ip or ip.lower() in ["本机", "local", "localhost"]:
            # 查询本机IP
            result += "📍 本机IP信息:\n"
            
            if platform.system() == "Windows":
                cmd_result = subprocess.run(
                    'ipconfig', shell=True, capture_output=True, text=True,
                    encoding='gbk', errors='replace', timeout=10
                )
                
                output = cmd_result.stdout
                # 提取IPv4地址
                ipv4_pattern = r'IPv4.*?:\s*(\d+\.\d+\.\d+\.\d+)'
                ips = re.findall(ipv4_pattern, output)
                
                if ips:
                    result += f"  IPv4地址: {', '.join(ips)}\n"
                
                # 提取MAC地址
                mac_pattern = r'物理地址.*?:\s*([0-9A-Fa-f-]+)'
                macs = re.findall(mac_pattern, output)
                if macs:
                    result += f"  MAC地址: {', '.join(macs)}\n"
                
                result += f"\n详细信息:\n{output[:1000]}\n"
        else:
            # 查询指定IP的地理位置信息
            result += f"📍 查询IP: {ip}\n\n"
            
            try:
                # 使用ipinfo.io API
                response = requests.get(f"https://ipinfo.io/{ip}/json", timeout=5)
                if response.status_code == 200:
                    data = response.json()
                    result += f"  IP地址: {data.get('ip', 'N/A')}\n"
                    result += f"  城市: {data.get('city', 'N/A')}\n"
                    result += f"  地区: {data.get('region', 'N/A')}\n"
                    result += f"  国家: {data.get('country', 'N/A')}\n"
                    result += f"  位置: {data.get('loc', 'N/A')}\n"
                    result += f"  组织: {data.get('org', 'N/A')}\n"
                else:
                    result += "  ⚠️ 无法获取IP地理位置信息\n"
            except Exception as e:
                result += f"  ❌ 查询失败: {str(e)}\n"
        
        return result
        
    except Exception as e:
        return f"❌ IP信息查询错误: {str(e)}"


def run_wifi_scan() -> str:
    """扫描WiFi网络"""
    try:
        if platform.system() != "Windows":
            return "❌ 此功能仅支持Windows系统"
        
        result = "📶 WiFi网络扫描\n"
        result += "=" * 50 + "\n\n"
        
        # 使用netsh命令扫描WiFi
        cmd_result = subprocess.run(
            'netsh wlan show networks mode=bssid', 
            shell=True, capture_output=True, text=True,
            encoding='gbk', errors='replace', timeout=30
        )
        
        if cmd_result.returncode == 0:
            output = cmd_result.stdout
            
            # 解析WiFi信息
            networks = []
            current_network = {}
            
            for line in output.split('\n'):
                line = line.strip()
                
                if line.startswith('SSID'):
                    if current_network:
                        networks.append(current_network)
                    parts = line.split(':', 1)
                    if len(parts) == 2:
                        ssid = parts[1].strip()
                        current_network = {'ssid': ssid}
                elif '信号' in line or 'Signal' in line:
                    parts = line.split(':', 1)
                    if len(parts) == 2:
                        current_network['signal'] = parts[1].strip()
                elif '身份验证' in line or 'Authentication' in line:
                    parts = line.split(':', 1)
                    if len(parts) == 2:
                        current_network['auth'] = parts[1].strip()
                elif '信道' in line or 'Channel' in line:
                    parts = line.split(':', 1)
                    if len(parts) == 2:
                        current_network['channel'] = parts[1].strip()
            
            if current_network:
                networks.append(current_network)
            
            # 格式化输出
            if networks:
                result += f"发现 {len(networks)} 个WiFi网络:\n\n"
                for i, net in enumerate(networks, 1):
                    result += f"{i}. SSID: {net.get('ssid', 'N/A')}\n"
                    result += f"   信号: {net.get('signal', 'N/A')}\n"
                    result += f"   加密: {net.get('auth', 'N/A')}\n"
                    result += f"   信道: {net.get('channel', 'N/A')}\n\n"
            else:
                result += "未发现WiFi网络\n"
        else:
            result += f"❌ 扫描失败: {cmd_result.stderr}\n"
        
        return result
        
    except Exception as e:
        return f"❌ WiFi扫描错误: {str(e)}"


def run_host_discovery(network: str = "192.168.1.0/24") -> str:
    """主机发现 - 扫描网络中的活动主机"""
    try:
        import ipaddress
        
        result = f"🔍 主机发现 - {network}\n"
        result += "=" * 50 + "\n"
        result += "正在扫描网络中的活动主机...\n\n"
        
        # 解析网络
        try:
            net = ipaddress.ip_network(network, strict=False)
        except ValueError:
            return f"❌ 无效的网络地址: {network}\n请使用格式如: 192.168.1.0/24"
        
        # 限制扫描范围
        hosts = list(net.hosts())
        if len(hosts) > 254:
            result += f"⚠️ 网络太大({len(hosts)}个主机)，仅扫描前254个\n\n"
            hosts = hosts[:254]
        
        active_hosts = []
        
        def ping_host(ip):
            try:
                cmd = f'ping -n 1 -w 500 {ip}'
                r = subprocess.run(cmd, shell=True, capture_output=True, text=True,
                                 encoding='gbk', errors='replace', timeout=2,
                                 startupinfo=subprocess.STARTUPINFO() if platform.system() == "Windows" else None)
                if r.returncode == 0:
                    return str(ip)
            except:
                pass
            return None
        
        # 使用线程池加速扫描
        with ThreadPoolExecutor(max_workers=50) as executor:
            futures = {executor.submit(ping_host, ip): ip for ip in hosts}
            for future in as_completed(futures):
                host = future.result()
                if host:
                    active_hosts.append(host)
        
        # 输出结果
        if active_hosts:
            result += f"✅ 发现 {len(active_hosts)} 个活动主机:\n\n"
            for host in sorted(active_hosts, key=lambda x: [int(p) for p in x.split('.')]):
                result += f"  • {host}\n"
        else:
            result += "❌ 未发现活动主机\n"
        
        result += f"\n扫描完成! 共扫描 {len(hosts)} 个地址\n"
        
        return result
        
    except Exception as e:
        return f"❌ 主机发现错误: {str(e)}"


def run_mac_lookup(mac: str) -> str:
    """MAC地址厂商查询"""
    try:
        # 清理MAC地址格式
        mac_clean = re.sub(r'[^0-9A-Fa-f]', '', mac).upper()
        
        if len(mac_clean) < 6:
            return "❌ MAC地址格式错误，至少需要6位"
        
        result = f"🔍 MAC地址查询: {mac}\n"
        result += "=" * 50 + "\n\n"
        
        # 提取OUI (前6位)
        oui = mac_clean[:6]
        result += f"OUI: {oui}\n\n"
        
        # 尝试从本地oui.txt文件查询
        try:
            with open('oui.txt', 'r', encoding='utf-8', errors='ignore') as f:
                for line in f:
                    if oui in line:
                        result += f"厂商信息: {line.strip()}\n"
                        break
                else:
                    result += "未找到厂商信息（本地数据库）\n"
        except FileNotFoundError:
            result += "⚠️ 本地OUI数据库不存在\n"
        
        # 尝试在线查询
        try:
            api_url = f"https://api.macvendors.com/{mac}"
            response = requests.get(api_url, timeout=5)
            if response.status_code == 200:
                vendor = response.text.strip()
                result += f"\n在线查询结果: {vendor}\n"
        except:
            pass
        
        return result
        
    except Exception as e:
        return f"❌ MAC地址查询错误: {str(e)}"


def run_wifi_password_view() -> str:
    """查看已保存的WiFi密码"""
    try:
        if platform.system() != "Windows":
            return "❌ 此功能仅支持Windows系统"
        
        result = "🔐 WiFi密码查看\n"
        result += "=" * 50 + "\n\n"
        
        # 获取所有WiFi配置文件
        cmd_result = subprocess.run(
            'netsh wlan show profiles', 
            shell=True, capture_output=True, text=True,
            encoding='gbk', errors='replace', timeout=10
        )
        
        if cmd_result.returncode != 0:
            return "❌ 获取WiFi配置失败，可能需要管理员权限"
        
        # 解析SSID列表
        ssids = []
        for line in cmd_result.stdout.split('\n'):
            if '所有用户配置文件' in line or 'All User Profile' in line:
                parts = line.split(':', 1)
                if len(parts) == 2:
                    ssid = parts[1].strip()
                    ssids.append(ssid)
        
        if not ssids:
            return "未找到已保存的WiFi配置"
        
        result += f"找到 {len(ssids)} 个WiFi配置:\n\n"
        
        # 获取每个WiFi的密码
        for ssid in ssids:
            try:
                cmd = f'netsh wlan show profile name="{ssid}" key=clear'
                pwd_result = subprocess.run(
                    cmd, shell=True, capture_output=True, text=True,
                    encoding='gbk', errors='replace', timeout=10
                )
                
                password = "无密码"
                for line in pwd_result.stdout.split('\n'):
                    if '关键内容' in line or 'Key Content' in line:
                        parts = line.split(':', 1)
                        if len(parts) == 2:
                            password = parts[1].strip()
                            break
                
                result += f"📶 {ssid}\n"
                result += f"   密码: {password}\n\n"
                
            except Exception as e:
                result += f"📶 {ssid}\n"
                result += f"   密码: 获取失败 ({str(e)})\n\n"
        
        result += "💡 提示: 如果显示'需要管理员权限'，请以管理员身份运行程序\n"
        
        return result
        
    except Exception as e:
        return f"❌ WiFi密码查看错误: {str(e)}"


def run_route_table_view() -> str:
    """查看路由表"""
    try:
        result = "🛣️ 路由表\n"
        result += "=" * 50 + "\n\n"
        
        if platform.system() == "Windows":
            cmd = 'route print'
            encoding = 'gbk'
        else:
            cmd = 'route -n'
            encoding = 'utf-8'
        
        cmd_result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True,
            encoding=encoding, errors='replace', timeout=10
        )
        
        if cmd_result.returncode == 0:
            result += cmd_result.stdout[:3000]
        else:
            result += f"❌ 获取路由表失败: {cmd_result.stderr}"
        
        return result
        
    except Exception as e:
        return f"❌ 路由表查看错误: {str(e)}"


def run_network_health_check() -> str:
    """网络健康检查 - 综合诊断"""
    try:
        result = "🏥 网络健康检查\n"
        result += "=" * 50 + "\n\n"
        
        # 1. 检查网络连接
        result += "1️⃣ 检查网络连接...\n"
        ping_result = run_ping("www.baidu.com", count=2)
        if "成功" in ping_result:
            result += "   ✅ 网络连接正常\n\n"
        else:
            result += "   ❌ 网络连接异常\n\n"
        
        # 2. 检查DNS解析
        result += "2️⃣ 检查DNS解析...\n"
        dns_result = run_dns_query("www.baidu.com")
        if "Address" in dns_result or "地址" in dns_result:
            result += "   ✅ DNS解析正常\n\n"
        else:
            result += "   ❌ DNS解析异常\n\n"
        
        # 3. 检查网关
        result += "3️⃣ 检查默认网关...\n"
        gw_result = run_network_info("gateway")
        if "默认网关" in gw_result and any(c.isdigit() for c in gw_result):
            result += "   ✅ 网关配置正常\n"
            result += f"   {gw_result.split(':')[1].strip() if ':' in gw_result else 'N/A'}\n\n"
        else:
            result += "   ⚠️ 未检测到网关\n\n"
        
        # 4. 检查公网连接
        result += "4️⃣ 检查公网连接...\n"
        public_ip_result = run_public_ip()
        if "公网IP" in public_ip_result:
            result += f"   ✅ {public_ip_result}\n\n"
        else:
            result += "   ❌ 无法获取公网IP\n\n"
        
        # 5. 端口连通性测试
        result += "5️⃣ 检查常用端口...\n"
        common_ports = [80, 443]
        for port in common_ports:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(2)
                r = sock.connect_ex(("www.baidu.com", port))
                sock.close()
                if r == 0:
                    result += f"   ✅ 端口 {port} 可达\n"
                else:
                    result += f"   ❌ 端口 {port} 不可达\n"
            except:
                result += f"   ❌ 端口 {port} 测试失败\n"
        
        result += "\n" + "=" * 50 + "\n"
        result += "健康检查完成!\n"
        
        return result
        
    except Exception as e:
        return f"❌ 网络健康检查错误: {str(e)}"


def run_dhcp_detection(interface: str = "auto") -> str:
    """DHCP主动检测 - 发送DHCP Discover包检测网络中的DHCP服务器"""
    try:
        result = "🔍 DHCP主动检测\n"
        result += "=" * 50 + "\n\n"
        
        # 获取网络适配器列表
        interfaces = _get_network_interfaces_for_dhcp()
        
        if not interfaces:
            return "❌ 未找到可用的网络适配器"
        
        # 根据参数选择网卡
        selected_interfaces = []
        
        if interface == "auto" or interface == "全网卡":
            # 自动模式或全网卡：选择所有网卡
            selected_interfaces = interfaces
            result += f"📡 检测模式: 全网卡扫描\n"
            result += f"📋 找到 {len(interfaces)} 个网络适配器\n\n"
        else:
            # 指定网卡：根据IP或名称匹配
            for iface in interfaces:
                if interface in iface['ip'] or interface in iface['name']:
                    selected_interfaces.append(iface)
            
            if not selected_interfaces:
                result += f"❌ 未找到匹配的网卡: {interface}\n\n"
                result += "可用的网卡列表:\n"
                for idx, iface in enumerate(interfaces, 1):
                    result += f"  {idx}. {iface['name']} - {iface['ip']}\n"
                return result
            
            result += f"📡 检测模式: 指定网卡\n"
            result += f"📋 匹配到 {len(selected_interfaces)} 个网络适配器\n\n"
        
        # 对每个选中的网卡进行DHCP检测
        dhcp_servers_found = []
        
        for idx, iface in enumerate(selected_interfaces, 1):
            result += f"【网卡 {idx}】\n"
            result += f"名称: {iface['name']}\n"
            result += f"IP: {iface['ip']}\n"
            result += f"MAC: {iface['mac']}\n"
            result += f"状态: 发送DHCP Discover包...\n"
            
            # 发送DHCP Discover
            dhcp_result = _send_dhcp_discover_simple(iface, timeout=10)
            
            if dhcp_result:
                if 'error' in dhcp_result:
                    result += f"❌ 错误: {dhcp_result['message']}\n\n"
                else:
                    # 成功检测到DHCP服务器
                    dhcp_server_ip = dhcp_result.get('dhcp_server', dhcp_result.get('source_addr', '未知'))
                    offered_ip = dhcp_result.get('your_ip', '未知')
                    
                    result += f"✅ 检测到DHCP服务器!\n"
                    result += f"   DHCP服务器: {dhcp_server_ip}\n"
                    result += f"   提供的IP: {offered_ip}\n"
                    
                    if 'subnet_mask' in dhcp_result:
                        result += f"   子网掩码: {dhcp_result['subnet_mask']}\n"
                    
                    if 'router' in dhcp_result:
                        result += f"   网关: {dhcp_result['router']}\n"
                    
                    if 'dns_servers' in dhcp_result:
                        result += f"   DNS服务器: {', '.join(dhcp_result['dns_servers'])}\n"
                    
                    if 'lease_time' in dhcp_result:
                        lease_hours = dhcp_result['lease_time'] // 3600
                        result += f"   租约时间: {dhcp_result['lease_time']}秒 ({lease_hours}小时)\n"
                    
                    dhcp_servers_found.append({
                        'interface': iface['name'],
                        'server': dhcp_server_ip,
                        'offered_ip': offered_ip
                    })
                    
                    result += "\n"
            else:
                result += f"⚠️ 未检测到DHCP服务器响应（超时）\n\n"
        
        # 总结
        result += "=" * 50 + "\n"
        result += f"📊 检测总结\n"
        result += f"   扫描网卡数: {len(selected_interfaces)}\n"
        result += f"   发现DHCP服务器: {len(dhcp_servers_found)} 个\n"
        
        if dhcp_servers_found:
            unique_servers = set(item['server'] for item in dhcp_servers_found)
            result += f"\n💡 检测到的DHCP服务器: {', '.join(unique_servers)}\n"
        else:
            result += f"\n⚠️ 提示: 未检测到任何DHCP服务器响应\n"
            result += f"   可能原因:\n"
            result += f"   1. 网络中没有DHCP服务器\n"
            result += f"   2. 需要管理员权限（请以管理员身份运行）\n"
            result += f"   3. 防火墙阻止了DHCP通信\n"
        
        return result
        
    except Exception as e:
        return f"❌ DHCP检测错误: {str(e)}"


def run_lan_speed_test(target_ip: str, duration: int = 10) -> str:
    """局域网测速"""
    try:
        result = f"🚀 局域网测速 - {target_ip}\n"
        result += "=" * 50 + "\n\n"
        
        # 使用iperf3的简化版本 - 通过大量ping测试估算
        result += f"正在测试到 {target_ip} 的连接速度...\n\n"
        
        # 1. 延迟测试
        result += "1️⃣ 延迟测试:\n"
        ping_result = run_ping(target_ip, count=10)
        result += f"{ping_result}\n\n"
        
        # 2. 端口连通性测试
        result += "2️⃣ TCP连接测试:\n"
        test_ports = [80, 445, 3389, 22]
        open_ports = []
        
        for port in test_ports:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(1)
                r = sock.connect_ex((target_ip, port))
                sock.close()
                if r == 0:
                    open_ports.append(port)
                    result += f"   ✅ 端口 {port} 开放\n"
            except:
                pass
        
        if not open_ports:
            result += "   ⚠️ 未发现开放的常用端口\n"
        
        result += "\n💡 提示: 如需精确测速，建议使用iperf3等专业工具\n"
        
        return result
        
    except Exception as e:
        return f"❌ 局域网测速错误: {str(e)}"


def run_session_test(host: str, port: int = 80, max_connections: int = 1000) -> str:
    """会话数测试 - 测试最大并发连接数"""
    try:
        result = f"🔗 会话数测试 - {host}:{port}\n"
        result += "=" * 50 + "\n\n"
        
        result += f"测试参数:\n"
        result += f"  目标: {host}:{port}\n"
        result += f"  最大连接数: {max_connections}\n"
        result += f"  延迟: 100ms\n"
        result += f"  线程数: 10\n\n"
        
        result += "正在测试最大并发连接数...\n\n"
        
        import time
        from concurrent.futures import ThreadPoolExecutor, as_completed
        
        start_time = time.time()
        success_count = 0
        fail_count = 0
        active_connections = []
        max_reached = 0
        
        def create_connection(index):
            """创建单个连接"""
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(5)
                sock.connect((host, port))
                return (True, sock, index)
            except Exception as e:
                return (False, None, index)
        
        # 使用线程池并发创建连接
        with ThreadPoolExecutor(max_workers=10) as executor:
            futures = []
            
            # 分批创建连接
            batch_size = 100
            for batch_start in range(0, max_connections, batch_size):
                batch_end = min(batch_start + batch_size, max_connections)
                
                # 提交本批次的连接任务
                for i in range(batch_start, batch_end):
                    future = executor.submit(create_connection, i)
                    futures.append(future)
                    time.sleep(0.1)  # 100ms延迟
                
                # 检查本批次结果
                for future in as_completed(futures[batch_start:batch_end]):
                    success, sock, idx = future.result()
                    
                    if success:
                        success_count += 1
                        active_connections.append(sock)
                        max_reached = success_count
                    else:
                        fail_count += 1
                        # 如果连续失败太多，提前结束
                        if fail_count >= 100:
                            result += f"⚠️ 连续失败{fail_count}次，停止测试\n\n"
                            break
                
                # 如果失败太多，停止测试
                if fail_count >= 100:
                    break
                
                # 每批次后报告进度
                if batch_end % 500 == 0 or batch_end == max_connections:
                    result += f"  进度: {batch_end}/{max_connections} | 成功: {success_count} | 失败: {fail_count}\n"
        
        # 关闭所有连接
        result += f"\n正在关闭 {len(active_connections)} 个连接...\n"
        for sock in active_connections:
            try:
                sock.close()
            except:
                pass
        
        elapsed = time.time() - start_time
        
        # 统计结果
        result += "\n" + "=" * 50 + "\n"
        result += "📊 测试结果:\n"
        result += f"  测试时长: {elapsed:.2f}秒\n"
        result += f"  尝试连接: {success_count + fail_count}\n"
        result += f"  成功连接: {success_count}\n"
        result += f"  失败连接: {fail_count}\n"
        result += f"  最大并发: {max_reached}\n"
        
        if success_count > 0:
            success_rate = (success_count / (success_count + fail_count)) * 100
            result += f"  成功率: {success_rate:.1f}%\n"
        
        # 评估结果
        result += "\n💡 评估:\n"
        if max_reached >= 5000:
            result += "  ✅ 优秀 - 支持大量并发连接\n"
        elif max_reached >= 2000:
            result += "  ✅ 良好 - 支持较多并发连接\n"
        elif max_reached >= 1000:
            result += "  ⚠️ 一般 - 支持中等并发连接\n"
        elif max_reached >= 500:
            result += "  ⚠️ 较差 - 并发能力有限\n"
        else:
            result += "  ❌ 很差 - 并发能力不足\n"
        
        result += f"\n💡 提示: 实际最大并发连接数为 {max_reached}\n"
        result += "=" * 50 + "\n"
        
        return result
        
    except Exception as e:
        return f"❌ 会话数测试错误: {str(e)}"


def run_camera_scan(network: str = "192.168.1.0/24") -> str:
    """摄像头扫描 - 扫描常见摄像头端口"""
    try:
        import ipaddress
        
        result = f"📹 摄像头扫描 - {network}\n"
        result += "=" * 50 + "\n\n"
        
        # 常见摄像头端口
        camera_ports = [80, 81, 554, 8000, 8080, 8081, 8554, 9000]
        
        result += f"扫描端口: {', '.join(map(str, camera_ports))}\n"
        result += "正在扫描...\n\n"
        
        # 解析网络
        try:
            net = ipaddress.ip_network(network, strict=False)
        except ValueError:
            return f"❌ 无效的网络地址: {network}"
        
        # 限制扫描范围
        hosts = list(net.hosts())
        if len(hosts) > 254:
            result += f"⚠️ 网络太大，仅扫描前254个主机\n\n"
            hosts = hosts[:254]
        
        found_devices = []
        
        def scan_camera(ip, port):
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(0.5)
                r = sock.connect_ex((str(ip), port))
                sock.close()
                if r == 0:
                    return (str(ip), port)
            except:
                pass
            return None
        
        # 扫描
        with ThreadPoolExecutor(max_workers=100) as executor:
            futures = []
            for ip in hosts:
                for port in camera_ports:
                    futures.append(executor.submit(scan_camera, ip, port))
            
            for future in as_completed(futures):
                device = future.result()
                if device:
                    found_devices.append(device)
        
        # 输出结果
        if found_devices:
            result += f"✅ 发现 {len(found_devices)} 个可能的摄像头设备:\n\n"
            
            # 按IP分组
            devices_by_ip = {}
            for ip, port in found_devices:
                if ip not in devices_by_ip:
                    devices_by_ip[ip] = []
                devices_by_ip[ip].append(port)
            
            for ip, ports in sorted(devices_by_ip.items()):
                result += f"  📹 {ip}\n"
                result += f"     开放端口: {', '.join(map(str, sorted(ports)))}\n"
                result += f"     访问地址: http://{ip}:{ports[0]}\n\n"
        else:
            result += "❌ 未发现摄像头设备\n"
        
        result += "\n💡 提示: 请确认设备权限后再访问\n"
        
        return result
        
    except Exception as e:
        return f"❌ 摄像头扫描错误: {str(e)}"


def run_arp_table_view() -> str:
    """查看ARP表"""
    try:
        result = "📋 ARP表\n"
        result += "=" * 50 + "\n\n"
        
        if platform.system() == "Windows":
            cmd = 'arp -a'
            encoding = 'gbk'
        else:
            cmd = 'arp -n'
            encoding = 'utf-8'
        
        cmd_result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True,
            encoding=encoding, errors='replace', timeout=10
        )
        
        if cmd_result.returncode == 0:
            result += cmd_result.stdout[:2000]
        else:
            result += f"❌ 获取ARP表失败: {cmd_result.stderr}"
        
        return result
        
    except Exception as e:
        return f"❌ ARP表查看错误: {str(e)}"


def run_ip_conflict_detection(ip_range: str = "192.168.1.1-254", interface: str = "auto") -> str:
    """IP冲突检测 - 使用ARP扫描检测IP冲突"""
    try:
        result = f"🔍 IP冲突检测 - {ip_range}\n"
        result += "=" * 50 + "\n\n"
        
        # 解析IP范围
        import ipaddress
        ip_list = []
        
        if '/' in ip_range:
            # CIDR格式
            try:
                network = ipaddress.ip_network(ip_range, strict=False)
                ip_list = [str(ip) for ip in network.hosts()]
                if len(ip_list) > 254:
                    result += f"⚠️ 网络太大({len(ip_list)}个IP)，仅检测前254个\n\n"
                    ip_list = ip_list[:254]
            except ValueError:
                return f"❌ 无效的CIDR格式: {ip_range}"
        elif '-' in ip_range:
            # 范围格式: 192.168.1.1-254
            parts = ip_range.rsplit('.', 1)
            if len(parts) == 2:
                prefix = parts[0]
                range_part = parts[1]
                if '-' in range_part:
                    start, end = range_part.split('-', 1)
                    try:
                        start_num = int(start)
                        end_num = int(end)
                        for i in range(start_num, end_num + 1):
                            ip_list.append(f"{prefix}.{i}")
                    except ValueError:
                        return f"❌ 无效的IP范围: {ip_range}"
        else:
            # 单个IP
            ip_list = [ip_range]
        
        if not ip_list:
            return "❌ 无效的IP范围"
        
        result += f"检测范围: {len(ip_list)} 个IP地址\n"
        result += "检测方法: ARP扫描\n\n"
        result += "正在扫描...\n\n"
        
        # 使用ARP扫描检测
        conflicts = {}
        active_ips = {}
        
        def check_ip(ip):
            try:
                # 使用ping测试IP是否活动
                if platform.system() == "Windows":
                    cmd = f'ping -n 1 -w 500 {ip}'
                else:
                    cmd = f'ping -c 1 -W 1 {ip}'
                
                startupinfo = None
                if platform.system() == "Windows":
                    startupinfo = subprocess.STARTUPINFO()
                    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                    startupinfo.wShowWindow = subprocess.SW_HIDE
                
                r = subprocess.run(cmd, shell=True, capture_output=True, text=True,
                                 encoding='gbk' if platform.system() == "Windows" else 'utf-8',
                                 errors='replace', timeout=2, startupinfo=startupinfo)
                
                if r.returncode == 0:
                    # 获取MAC地址
                    # Windows: arp -a 显示所有，需要过滤指定IP
                    # Linux: arp -n 显示数字格式
                    if platform.system() == "Windows":
                        arp_cmd = 'arp -a'
                    else:
                        arp_cmd = f'arp -n {ip}'
                    
                    arp_result = subprocess.run(arp_cmd, shell=True, capture_output=True, text=True,
                                              encoding='gbk' if platform.system() == "Windows" else 'utf-8',
                                              errors='replace', timeout=2, startupinfo=startupinfo)
                    
                    if arp_result.returncode == 0:
                        # 在输出中查找对应IP的MAC地址
                        for line in arp_result.stdout.split('\n'):
                            if ip in line:
                                # Windows格式: 192.168.1.1      00-11-22-33-44-55     动态
                                # Linux格式:   192.168.1.1      ether   00:11:22:33:44:55   C   eth0
                                
                                # 匹配完整MAC地址（支持 : 和 - 分隔符）
                                mac_pattern = r'[0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}'
                                mac_match = re.search(mac_pattern, line)
                                if mac_match:
                                    mac = mac_match.group(0)
                                    return (ip, mac)
            except:
                pass
            return None
        
        # 使用线程池加速扫描
        with ThreadPoolExecutor(max_workers=50) as executor:
            futures = {executor.submit(check_ip, ip): ip for ip in ip_list}
            for future in as_completed(futures):
                res = future.result()
                if res:
                    ip, mac = res
                    if mac in active_ips:
                        # 发现冲突
                        if mac not in conflicts:
                            conflicts[mac] = [active_ips[mac], ip]
                        else:
                            conflicts[mac].append(ip)
                    else:
                        active_ips[mac] = ip
        
        # 输出结果
        result += f"扫描完成！\n\n"
        result += f"活动IP数量: {len(active_ips)}\n"
        
        if conflicts:
            result += f"\n⚠️ 发现 {len(conflicts)} 个MAC地址冲突:\n\n"
            for mac, ips in conflicts.items():
                result += f"🔴 MAC地址: {mac}\n"
                result += f"   冲突IP: {', '.join(ips)}\n"
                result += f"   冲突数量: {len(ips)}\n\n"
        else:
            result += f"\n✅ 未发现IP冲突\n"
        
        # 显示活动IP列表（前20个）
        if active_ips:
            result += f"\n活动IP列表（前20个）:\n"
            for i, (mac, ip) in enumerate(list(active_ips.items())[:20], 1):
                result += f"  {i}. {ip} - {mac}\n"
            
            if len(active_ips) > 20:
                result += f"  ... 还有 {len(active_ips) - 20} 个\n"
        
        return result
        
    except Exception as e:
        return f"❌ IP冲突检测错误: {str(e)}"


# ========== DHCP主动检测辅助函数 ==========

def _get_network_interfaces_for_dhcp():
    """获取网络适配器列表（用于DHCP检测）"""
    interfaces = []
    try:
        if platform.system() == "Windows":
            import ctypes
            from ctypes import wintypes
            
            iphlpapi = ctypes.windll.iphlpapi
            
            class IP_ADDR_STRING(ctypes.Structure):
                pass
            
            IP_ADDR_STRING._fields_ = [
                ("Next", ctypes.POINTER(IP_ADDR_STRING)),
                ("IpAddress", ctypes.c_char * 16),
                ("IpMask", ctypes.c_char * 16),
                ("Context", wintypes.DWORD),
            ]
            
            class IP_ADAPTER_INFO(ctypes.Structure):
                pass
            
            IP_ADAPTER_INFO._fields_ = [
                ("Next", ctypes.POINTER(IP_ADAPTER_INFO)),
                ("ComboIndex", wintypes.DWORD),
                ("AdapterName", ctypes.c_char * 260),
                ("Description", ctypes.c_char * 132),
                ("AddressLength", ctypes.c_uint),
                ("Address", ctypes.c_ubyte * 8),
                ("Index", wintypes.DWORD),
                ("Type", ctypes.c_uint),
                ("DhcpEnabled", wintypes.DWORD),
                ("CurrentIpAddress", ctypes.POINTER(IP_ADDR_STRING)),
                ("IpAddressList", IP_ADDR_STRING),
                ("GatewayList", IP_ADDR_STRING),
                ("DhcpServer", IP_ADDR_STRING),
                ("HaveWins", wintypes.BOOL),
                ("PrimaryWinsServer", IP_ADDR_STRING),
                ("SecondaryWinsServer", IP_ADDR_STRING),
                ("LeaseObtained", ctypes.c_int64),
                ("LeaseExpires", ctypes.c_int64),
            ]
            
            buf_len = wintypes.ULONG(15000)
            buf = ctypes.create_string_buffer(buf_len.value)
            
            if iphlpapi.GetAdaptersInfo(buf, ctypes.byref(buf_len)) == 0:
                adapter = ctypes.cast(buf, ctypes.POINTER(IP_ADAPTER_INFO)).contents
                
                while True:
                    ip_addr = adapter.IpAddressList.IpAddress.decode('utf-8').strip('\x00')
                    
                    if ip_addr and ip_addr != '0.0.0.0':
                        mac_bytes = bytes(adapter.Address[:adapter.AddressLength])
                        mac_str = ':'.join(f'{b:02X}' for b in mac_bytes)
                        
                        interfaces.append({
                            'name': adapter.Description.decode('utf-8', errors='ignore'),
                            'ip': ip_addr,
                            'mac': mac_str,
                            'index': adapter.Index,
                        })
                    
                    if not adapter.Next:
                        break
                    adapter = adapter.Next.contents
        else:
            # Linux/Mac
            try:
                import netifaces
                for iface in netifaces.interfaces():
                    addrs = netifaces.ifaddresses(iface)
                    if netifaces.AF_INET in addrs and netifaces.AF_LINK in addrs:
                        ip_info = addrs[netifaces.AF_INET][0]
                        mac_info = addrs[netifaces.AF_LINK][0]
                        interfaces.append({
                            'name': iface,
                            'ip': ip_info.get('addr'),
                            'mac': mac_info.get('addr'),
                            'index': None
                        })
            except ImportError:
                pass
    
    except Exception:
        pass
    
    return interfaces


def _mac_str_to_bytes(mac: str) -> bytes:
    """MAC地址字符串转字节"""
    mac = mac.replace(':', '').replace('-', '')
    return bytes.fromhex(mac)


def _ip_to_str(ip: bytes) -> str:
    """IP字节转字符串"""
    return '.'.join(str(b) for b in ip)


def _create_dhcp_discover(client_mac: bytes, xid: int) -> bytes:
    """创建DHCP DISCOVER数据包"""
    packet = bytearray()
    
    packet.append(0x01)  # Message type: Boot Request
    packet.append(0x01)  # Hardware type: Ethernet
    packet.append(0x06)  # Hardware address length: 6
    packet.append(0x00)  # Hops: 0
    
    packet.extend(struct.pack('!I', xid))
    
    packet.extend(struct.pack('!H', 0))  # Seconds elapsed
    packet.extend(struct.pack('!H', 0x8000))  # Bootp flags (broadcast)
    
    packet.extend(bytes(4))  # Client IP address
    packet.extend(bytes(4))  # Your IP address
    packet.extend(bytes(4))  # Server IP address
    packet.extend(bytes(4))  # Gateway IP address
    
    packet.extend(client_mac)  # Client MAC address
    packet.extend(bytes(10))   # Client hardware address padding
    
    packet.extend(bytes(64))   # Server host name
    packet.extend(bytes(128))  # Boot file name
    
    packet.extend(bytes([0x63, 0x82, 0x53, 0x63]))  # Magic cookie
    
    packet.extend(bytes([53, 1, 1]))  # DHCP Message Type: Discover
    packet.extend(bytes([55, 4, 1, 3, 6, 15]))  # Parameter Request List
    packet.append(255)  # End Option
    
    return bytes(packet)


def _parse_dhcp_options(options: bytes) -> dict:
    """解析DHCP选项"""
    result = {}
    i = 0
    
    while i < len(options):
        option_code = options[i]
        
        if option_code == 255:  # End
            break
        
        if option_code == 0:  # Padding
            i += 1
            continue
        
        if i + 1 >= len(options):
            break
        
        option_len = options[i + 1]
        
        if i + 2 + option_len > len(options):
            break
        
        option_data = options[i + 2:i + 2 + option_len]
        
        if option_code == 53:  # Message Type
            result['message_type'] = option_data[0]
        elif option_code == 54:  # DHCP Server Identifier
            result['dhcp_server'] = _ip_to_str(option_data)
        elif option_code == 1:  # Subnet Mask
            result['subnet_mask'] = _ip_to_str(option_data)
        elif option_code == 3:  # Router
            result['router'] = _ip_to_str(option_data)
        elif option_code == 6:  # DNS Servers
            dns_servers = []
            for j in range(0, len(option_data), 4):
                if j + 4 <= len(option_data):
                    dns_servers.append(_ip_to_str(option_data[j:j+4]))
            result['dns_servers'] = dns_servers
        elif option_code == 51:  # Lease Time
            result['lease_time'] = struct.unpack('!I', option_data)[0]
        elif option_code == 15:  # Domain Name
            result['domain_name'] = option_data.decode('utf-8', errors='ignore')
        
        i += 2 + option_len
    
    return result


def _parse_dhcp_packet(packet: bytes):
    """解析DHCP数据包"""
    if len(packet) < 240:
        return None
    
    op = packet[0]
    if op != 2:  # Boot Reply
        return None
    
    xid = struct.unpack('!I', packet[4:8])[0]
    yiaddr = packet[16:20]
    siaddr = packet[20:24]
    
    magic_cookie = packet[236:240]
    if magic_cookie != bytes([0x63, 0x82, 0x53, 0x63]):
        return None
    
    options = _parse_dhcp_options(packet[240:])
    
    result = {
        'xid': xid,
        'your_ip': _ip_to_str(yiaddr),
        'server_ip': _ip_to_str(siaddr),
    }
    result.update(options)
    
    return result


def _send_dhcp_discover_simple(interface: dict, timeout: int = 10) -> dict:
    """发送DHCP DISCOVER并等待响应（简化版）"""
    try:
        client_mac = _mac_str_to_bytes(interface['mac'])
        xid = random.randint(0, 0xFFFFFFFF)
        
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        # Windows下绑定到特定网卡IP
        if platform.system() == "Windows":
            sock.bind((interface['ip'], 68))
        else:
            sock.bind(('0.0.0.0', 68))
        
        sock.settimeout(timeout)
        
        discover_packet = _create_dhcp_discover(client_mac, xid)
        sock.sendto(discover_packet, ('255.255.255.255', 67))
        
        start_time = time.time()
        
        while time.time() - start_time < timeout:
            try:
                remaining_time = timeout - (time.time() - start_time)
                if remaining_time <= 0:
                    break
                
                sock.settimeout(remaining_time)
                data, addr = sock.recvfrom(4096)
                
                parsed = _parse_dhcp_packet(data)
                if parsed and parsed.get('xid') == xid:
                    if parsed.get('message_type') == 2:  # DHCP Offer
                        parsed['source_addr'] = addr[0]
                        sock.close()
                        return parsed
            
            except socket.timeout:
                break
            except Exception:
                continue
        
        sock.close()
        return None
    
    except PermissionError:
        return {'error': 'permission', 'message': '权限不足，请以管理员身份运行'}
    except Exception as e:
        return {'error': 'exception', 'message': str(e)}