From f777fae3d84e8dbf668f4f95124a82c98bf3cf05 Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Sat, 19 Sep 2020 19:05:12 +0800 Subject: [PATCH] Use the registry to edit System DNS instead of WMI, check network connection before start mode --- Netch/Controllers/MainController.cs | 7 ++ Netch/Controllers/Mode/NFController.cs | 11 ++- Netch/Controllers/Mode/TUNTAPController.cs | 82 ++++++---------------- Netch/Global.cs | 10 ++- Netch/Netch.csproj | 3 - Netch/Utils/DNS.cs | 67 ++++++------------ Netch/Utils/Utils.cs | 48 +++++++++++++ 7 files changed, 112 insertions(+), 116 deletions(-) diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs index 723f67b5..e9f93d7c 100644 --- a/Netch/Controllers/MainController.cs +++ b/Netch/Controllers/MainController.cs @@ -33,6 +33,13 @@ namespace Netch.Controllers } NativeMethods.FlushDNSResolverCache(); + + if (!Utils.Utils.SearchOutboundAdapter()) + { + MessageBoxX.Show("No internet connection"); + return false; + } + _ = Task.Run(Firewall.AddNetchFwRules); try diff --git a/Netch/Controllers/Mode/NFController.cs b/Netch/Controllers/Mode/NFController.cs index bf903fec..cb1ab0b8 100644 --- a/Netch/Controllers/Mode/NFController.cs +++ b/Netch/Controllers/Mode/NFController.cs @@ -1,9 +1,7 @@ using System; -using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.ServiceProcess; -using System.Text; using System.Threading.Tasks; using Netch.Models; using Netch.Utils; @@ -17,7 +15,7 @@ namespace Netch.Controllers private static readonly string BinDriver = string.Empty; private static readonly string SystemDriver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys"; - private static string[] _sysDns = { }; + private static string _sysDns; static NFController() { @@ -92,9 +90,8 @@ namespace Netch.Controllers if (Global.Settings.ModifySystemDNS) { // 备份并替换系统 DNS - _sysDns = DNS.getSystemDns(); - string[] dns = {"1.1.1.1", "8.8.8.8"}; - DNS.SetDNS(dns); + _sysDns = DNS.OutboundDNS; + DNS.OutboundDNS = "1.1.1.1,8.8.8.8"; } return aio_init(); @@ -106,7 +103,7 @@ namespace Netch.Controllers { if (Global.Settings.ModifySystemDNS) //恢复系统DNS - DNS.SetDNS(_sysDns); + DNS.OutboundDNS = _sysDns; }); aio_free(); diff --git a/Netch/Controllers/Mode/TUNTAPController.cs b/Netch/Controllers/Mode/TUNTAPController.cs index 3c46b16b..b7dfad88 100644 --- a/Netch/Controllers/Mode/TUNTAPController.cs +++ b/Netch/Controllers/Mode/TUNTAPController.cs @@ -18,7 +18,8 @@ namespace Netch.Controllers public class TUNTAPController : ModeController { // ByPassLan IP - private readonly List _bypassLanIPs = new List {"10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16"}; + private readonly List _bypassLanIPs = new List + {"10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16"}; private Mode _savedMode = new Mode(); private Server _savedServer = new Server(); @@ -56,7 +57,7 @@ namespace Netch.Controllers } // 搜索出口 - return SearchAdapters(); + return SearchTapAdapter(); } private readonly List _directIPs = new List(); @@ -75,7 +76,8 @@ namespace Netch.Controllers _directIPs.AddRange(Global.Settings.BypassIPs.Select(IPNetwork.Parse)); Logging.Info("绕行 → 服务器 IP"); - _directIPs.AddRange(_serverAddresses.Where(address => !IPAddress.IsLoopback(address)).Select(address => IPNetwork.Parse(address.ToString(), 32))); + _directIPs.AddRange(_serverAddresses.Where(address => !IPAddress.IsLoopback(address)) + .Select(address => IPNetwork.Parse(address.ToString(), 32))); Logging.Info("绕行 → 局域网 IP"); _directIPs.AddRange(_bypassLanIPs.Select(IPNetwork.Parse)); @@ -121,7 +123,9 @@ namespace Netch.Controllers } else { - _proxyIPs.AddRange(new[] {"1.1.1.1", "8.8.8.8", "9.9.9.9", "185.222.222.222"}.Select(ip => IPNetwork.Parse(ip, 32))); + _proxyIPs.AddRange( + new[] {"1.1.1.1", "8.8.8.8", "9.9.9.9", "185.222.222.222"}.Select(ip => + IPNetwork.Parse(ip, 32))); } } @@ -231,7 +235,8 @@ namespace Netch.Controllers else argument.Append($"-proxyServer 127.0.0.1:{Global.Settings.Socks5LocalPort} "); - argument.Append($"-tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\" "); + argument.Append( + $"-tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\" "); if (Global.Settings.TUNTAP.UseFakeDNS) argument.Append("-fakeDns "); @@ -256,22 +261,14 @@ namespace Netch.Controllers /// /// 搜索出口和TUNTAP适配器 /// - private static bool SearchAdapters() + public static bool SearchTapAdapter() { - // 寻找出口适配器 - if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) != 0) - { - Logging.Error("GetBestRoute 搜索失败(找不到出口适配器)"); - return false; - } - - Global.Adapter.Index = pRoute.dwForwardIfIndex; - // 搜索 TUN/TAP 适配器的索引 if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID = TUNTAP.GetComponentID())) { Logging.Info("找不到 TAP 适配器"); - if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), confirm: true) == DialogResult.OK) + if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), + confirm: true) == DialogResult.OK) { Configuration.addtap(); // 给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID @@ -289,42 +286,14 @@ namespace Netch.Controllers } } - // 根据 IP Index 寻找 出口适配器 - var errorAdaptersId = new List(); - try - { - var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => - { - try - { - return _.GetIPProperties().GetIPv4Properties().Index == Global.Adapter.Index; - } - catch (NetworkInformationException) - { - errorAdaptersId.Add(_.Id); - return false; - } - }); - Global.Adapter.Address = adapter.GetIPProperties().UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork).Address; - Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop); - Logging.Info($"出口 IPv4 地址:{Global.Adapter.Address}"); - Logging.Info($"出口 网关 地址:{Global.Adapter.Gateway}"); - Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Adapter.Index}"); - } - catch (Exception e) - { - Logging.Error($"找不到 IP Index 为 {Global.Adapter.Index} 的出口适配器: {e.Message}"); - PrintAdapters(); - return false; - } - // 根据 ComponentID 寻找 Tap适配器 try { var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.Id == Global.TUNTAP.ComponentID); Global.TUNTAP.Adapter = adapter; Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index; - Logging.Info($"TAP 适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}"); + Logging.Info( + $"TAP 适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}"); } catch (Exception e) { @@ -335,18 +304,10 @@ namespace Netch.Controllers _ => $"Tap 适配器其他异常: {e}" }; Logging.Error(msg); - PrintAdapters(); return false; } return true; - - void PrintAdapters() - { - Logging.Info("所有适配器:\n" + - NetworkInterface.GetAllNetworkInterfaces().Aggregate(string.Empty, (current, adapter) - => current + $"{ /*如果加了 ’*‘ 代表遍历中出现异常的适配器 */(errorAdaptersId.Contains(adapter.Id) ? "*" : "")}{adapter.Name} {adapter.Id} {adapter.Description}{Global.EOF}")); - } } @@ -362,7 +323,8 @@ namespace Netch.Controllers Delete } - private static void RouteAction(Action action, IEnumerable ipNetworks, RouteType routeType, int metric = 0) + private static void RouteAction(Action action, IEnumerable ipNetworks, RouteType routeType, + int metric = 0) { foreach (var address in ipNetworks) { @@ -382,8 +344,8 @@ namespace Netch.Controllers switch (routeType) { case RouteType.Gateway: - gateway = Global.Adapter.Gateway.ToString(); - index = Global.Adapter.Index; + gateway = Global.Outbound.Gateway.ToString(); + index = Global.Outbound.Index; break; case RouteType.TUNTAP: gateway = Global.Settings.TUNTAP.Gateway; @@ -395,8 +357,10 @@ namespace Netch.Controllers var result = action switch { - Action.Create => NativeMethods.CreateRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, metric), - Action.Delete => NativeMethods.DeleteRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, metric), + Action.Create => NativeMethods.CreateRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, + metric), + Action.Delete => NativeMethods.DeleteRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, + metric), _ => throw new ArgumentOutOfRangeException(nameof(action), action, null) }; diff --git a/Netch/Global.cs b/Netch/Global.cs index 52af0e52..d918dbe5 100644 --- a/Netch/Global.cs +++ b/Netch/Global.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.NetworkInformation; +using System.Net.Sockets; using System.Windows.Forms; using Netch.Forms; using Netch.Models; @@ -155,9 +157,9 @@ namespace Netch }; /// - /// 适配器 + /// 出口适配器 /// - public static class Adapter + public static class Outbound { /// /// 索引 @@ -167,12 +169,14 @@ namespace Netch /// /// 地址 /// - public static IPAddress Address; + public static IPAddress Address => Adapter.GetIPProperties().UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork).Address; /// /// 网关 /// public static IPAddress Gateway; + + public static NetworkInterface Adapter; } /// diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index 6acda02c..0e931ebe 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -73,9 +73,6 @@ - - - diff --git a/Netch/Utils/DNS.cs b/Netch/Utils/DNS.cs index ce7a8687..5b06bc99 100644 --- a/Netch/Utils/DNS.cs +++ b/Netch/Utils/DNS.cs @@ -1,9 +1,7 @@ using System; using System.Collections; -using System.Linq; -using System.Management; using System.Net; -using System.Net.NetworkInformation; +using Microsoft.Win32; namespace Netch.Utils { @@ -48,51 +46,32 @@ namespace Netch.Utils return null; } } - /// - /// 设置DNS - /// - /// - public static void SetDNS(string[] dns) - { - var wmi = new ManagementClass("Win32_NetworkAdapterConfiguration"); - var moc = wmi.GetInstances(); - ManagementBaseObject inPar = null; - ManagementBaseObject outPar = null; - foreach (ManagementObject mo in moc) - { - //如果没有启用IP设置的网络设备则跳过,如果是虚拟机网卡也跳过 - if (!(bool)mo["IPEnabled"] || - mo["Description"].ToString().Contains("Virtual") || - mo["Description"].ToString().Contains("VMware") || - mo["Description"].ToString().Contains("TAP")) - continue; - //设置DNS地址 - if (dns != null) + private static RegistryKey AdapterRegistry(bool write = false) + { + return Registry.LocalMachine.OpenSubKey( + $@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{Global.Outbound.Adapter.Id}", write); + } + + /// + /// 出口网卡 DNS + /// + /// 依赖 + /// + public static string OutboundDNS + { + get + { + try { - inPar = mo.GetMethodParameters("SetDNSServerSearchOrder"); - inPar["DNSServerSearchOrder"] = dns; - outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null); + return (string) AdapterRegistry().GetValue("NameServer"); + } + catch + { + return string.Empty; } } - } - /// - /// 从网卡获取ip设置信息 - /// - public static string[] getSystemDns() - { - var systemDns = new[] { "223.5.5.5", "1.1.1.1" }; - foreach (var network in NetworkInterface.GetAllNetworkInterfaces()) - if (!network.Description.Contains("Virtual") && - !network.Description.Contains("VMware") && - !network.Description.Contains("TAP") && - network.OperationalStatus == OperationalStatus.Up && - network.GetIPProperties()?.GatewayAddresses.Count != 0) - { - systemDns = network.GetIPProperties().DnsAddresses.Select(dns => dns.ToString()).ToArray(); - } - - return systemDns; + set => AdapterRegistry(true).SetValue("NameServer", value, RegistryValueKind.String); } } } \ No newline at end of file diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index 5a6cb63a..8c9aaedd 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; @@ -122,5 +124,51 @@ namespace Netch.Utils } public static string FileVersion(string file) => File.Exists(file) ? FileVersionInfo.GetVersionInfo(file).FileVersion : string.Empty; + + public static bool SearchOutboundAdapter() + { + // 寻找出口适配器 + if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), + 0, out var pRoute) != 0) + { + Logging.Error("GetBestRoute 搜索失败"); + return false; + } + + Global.Outbound.Index = pRoute.dwForwardIfIndex; + // 根据 IP Index 寻找 出口适配器 + try + { + var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => + { + try + { + return _.GetIPProperties().GetIPv4Properties().Index == Global.Outbound.Index; + } + catch + { + return false; + } + }); + Global.Outbound.Adapter = adapter; + Global.Outbound.Gateway = new IPAddress(pRoute.dwForwardNextHop); + Logging.Info($"出口 IPv4 地址:{Global.Outbound.Address}"); + Logging.Info($"出口 网关 地址:{Global.Outbound.Gateway}"); + Logging.Info( + $"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Outbound.Index}"); + return true; + } + catch (Exception) + { + Logging.Error("找不到出口IP所在网卡"); + return false; + } + } + + public static void LoggingAdapters(string id) + { + var adapter = NetworkInterface.GetAllNetworkInterfaces().First(adapter => adapter.Id == id); + Logging.Warning($"检索此网卡信息出错: {adapter.Name} {adapter.Id} {adapter.Description}"); + } } } \ No newline at end of file