using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace TcpConnectionMonitor
{
    public class TcpConnectionManager
    {
        // IPv4连接结构体
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW
        {
            public uint dwState;
            public uint dwLocalAddr;
            public uint dwLocalPort;
            public uint dwRemoteAddr;
            public uint dwRemotePort;
        }
        // IPv6连接结构体
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6ROW
        {
            public uint dwState;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            public uint localPort;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] remoteAddr;
            public uint remoteScopeId;
            public uint remotePort;
        }
        [DllImport("iphlpapi.dll", SetLastError = true)]
        public static extern int SetTcpEntry(ref MIB_TCPROW pTcpRow);
        [DllImport("iphlpapi.dll", SetLastError = true)]
        public static extern int SetTcpEntry6(ref MIB_TCP6ROW pTcp6Row);
        public static void DisconnectNonWhitelistedConnections(int targetPort, HashSet<string> whiteList)
        {
            IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
            TcpConnectionInformation[] connections = properties.GetActiveTcpConnections();
            foreach (TcpConnectionInformation connection in connections)
            {
                if (connection.LocalEndPoint.Port == targetPort)
                {
                    IPAddress remoteAddress = connection.RemoteEndPoint.Address;
                    string remoteIp = remoteAddress.ToString();
                    // 处理IPv6连接
                    if (remoteAddress.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        try
                        {
                            MIB_TCP6ROW row6 = new MIB_TCP6ROW
                            {
                                dwState = 12, // DELETE_TCB
                                localAddr = connection.LocalEndPoint.Address.GetAddressBytes(),
                                localPort = (uint)IPAddress.HostToNetworkOrder((short)connection.LocalEndPoint.Port),
                                remoteAddr = remoteAddress.GetAddressBytes(),
                                remotePort = (uint)IPAddress.HostToNetworkOrder((short)connection.RemoteEndPoint.Port),
                                localScopeId = 0,
                                remoteScopeId = 0
                            };
                            int result = SetTcpEntry6(ref row6);
                            Console.WriteLine(result == 0 ? 
                                $"已断开IPv6连接:{remoteIp}" : 
                                $"IPv6断开失败(错误码:{result}):{remoteIp}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"处理IPv6连接时出错:{ex.Message}");
                        }
                    }
                    // 处理IPv4连接
                    else if (!whiteList.Contains(remoteIp))
                    {
                        try
                        {
                            MIB_TCPROW row = new MIB_TCPROW
                            {
                                dwState = 12,
                                dwLocalAddr = BitConverter.ToUInt32(connection.LocalEndPoint.Address.GetAddressBytes(), 0),
                                dwLocalPort = (uint)IPAddress.HostToNetworkOrder((short)connection.LocalEndPoint.Port),
                                dwRemoteAddr = BitConverter.ToUInt32(remoteAddress.GetAddressBytes(), 0),
                                dwRemotePort = (uint)IPAddress.HostToNetworkOrder((short)connection.RemoteEndPoint.Port)
                            };
                            int result = SetTcpEntry(ref row);
                            Console.WriteLine(result == 0 ? 
                                $"已断开IPv4连接:{remoteIp}" : 
                                $"IPv4断开失败(错误码:{result}):{remoteIp}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"处理IPv4连接时出错:{ex.Message}");
                        }
                    }
                }
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            HashSet<string> whiteList = new HashSet<string>
            {
                "192.168.1.100",
                "10.0.0.5"
            };
            try
            {
                TcpConnectionManager.DisconnectNonWhitelistedConnections(3389, whiteList);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"运行时错误:{ex.Message}");
            }
        }
    }
}