Cut TAP Network Sharing

This commit is contained in:
ChsBuffer
2021-02-14 21:40:04 +08:00
parent dacebc0eaa
commit fd410ea388
5 changed files with 1 additions and 582 deletions

View File

@@ -79,7 +79,7 @@ namespace Netch.Forms
this.UseCustomDNSCheckBox = new System.Windows.Forms.CheckBox();
this.ProxyDNSCheckBox = new System.Windows.Forms.CheckBox();
this.UseFakeDNSCheckBox = new System.Windows.Forms.CheckBox();
this.ICSCheckBox = new System.Windows.Forms.CheckBox();
new System.Windows.Forms.CheckBox();
this.GlobalBypassIPsButton = new System.Windows.Forms.Button();
this.v2rayTabPage = new System.Windows.Forms.TabPage();
this.TLSAllowInsecureCheckBox = new System.Windows.Forms.CheckBox();
@@ -506,7 +506,6 @@ namespace Netch.Forms
this.TUNTAPGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
this.TUNTAPGroupBox.Controls.Add(this.ProxyDNSCheckBox);
this.TUNTAPGroupBox.Controls.Add(this.UseFakeDNSCheckBox);
this.TUNTAPGroupBox.Controls.Add(this.ICSCheckBox);
this.TUNTAPGroupBox.Location = new System.Drawing.Point(6, 6);
this.TUNTAPGroupBox.Name = "TUNTAPGroupBox";
this.TUNTAPGroupBox.Size = new System.Drawing.Size(420, 187);
@@ -615,19 +614,6 @@ namespace Netch.Forms
this.UseFakeDNSCheckBox.UseVisualStyleBackColor = true;
this.UseFakeDNSCheckBox.Visible = false;
//
// ICSCheckBox
//
this.ICSCheckBox.AutoSize = true;
this.ICSCheckBox.Enabled = false;
this.ICSCheckBox.Location = new System.Drawing.Point(261, 160);
this.ICSCheckBox.Name = "ICSCheckBox";
this.ICSCheckBox.Size = new System.Drawing.Size(138, 16);
this.ICSCheckBox.TabIndex = 11;
this.ICSCheckBox.Text = "Tap Network Sharing";
this.ICSCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.ICSCheckBox.UseVisualStyleBackColor = true;
this.ICSCheckBox.Click += new System.EventHandler(this.ICSCheckBox_CheckedChanged);
//
// GlobalBypassIPsButton
//
this.GlobalBypassIPsButton.Location = new System.Drawing.Point(6, 199);
@@ -1072,7 +1058,6 @@ namespace Netch.Forms
private System.Windows.Forms.GroupBox TUNTAPGroupBox;
private System.Windows.Forms.CheckBox UseFakeDNSCheckBox;
private System.Windows.Forms.CheckBox ProxyDNSCheckBox;
private System.Windows.Forms.CheckBox ICSCheckBox;
private System.Windows.Forms.CheckBox UseCustomDNSCheckBox;
private System.Windows.Forms.Label TUNTAPDNSLabel;
private System.Windows.Forms.TextBox TUNTAPDNSTextBox;

View File

@@ -153,20 +153,6 @@ namespace Netch.Forms
b => Global.Settings.TUNTAP.UseFakeDNS = b,
Global.Settings.TUNTAP.UseFakeDNS);
try
{
var icsHelperEnabled = ICSHelper.Enabled;
if (icsHelperEnabled != null)
{
ICSCheckBox.Enabled = true;
ICSCheckBox.Checked = (bool) icsHelperEnabled;
}
}
catch
{
// ignored
}
#endregion
#region V2Ray
@@ -364,35 +350,6 @@ namespace Netch.Forms
Close();
}
private async void ICSCheckBox_CheckedChanged(object sender, EventArgs e)
{
try
{
ICSCheckBox.Enabled = false;
await Task.Run(() =>
{
if (ICSCheckBox.Checked)
{
if (!(ICSHelper.Enabled ?? true))
ICSCheckBox.Checked = ICSHelper.Enable();
}
else
{
ICSHelper.Disable();
}
});
}
catch (Exception exception)
{
ICSCheckBox.Checked = false;
Logging.Error(exception.ToString());
}
finally
{
ICSCheckBox.Enabled = true;
}
}
private void BindTextBox(TextBox control, Func<string, bool> check, Action<string> save, object value)
{
BindTextBox<string>(control, check, save, value);

View File

@@ -1,114 +0,0 @@
using System;
using NETCONLib;
namespace Netch.Models.WinFW
{
public class NetworkConnection : INetConnection, INetConnectionProps, INetSharingConfiguration
{
private readonly INetConnection _icsConn;
private readonly NetSharingManager _icsMgr;
public NetworkConnection(INetConnection icsConnection)
{
_icsMgr = new NetSharingManagerClass();
_icsConn = icsConnection;
}
public void Connect()
{
_icsConn.Connect();
}
public void Delete()
{
_icsConn.Delete();
}
public void Duplicate(string pszwDuplicateName, out INetConnection ppCon)
{
_icsConn.Duplicate(pszwDuplicateName, out ppCon);
}
public void Disconnect()
{
_icsConn.Disconnect();
}
public void GetProperties(IntPtr ppProps)
{
_icsConn.GetProperties(ppProps);
}
public void Rename(string pszwNewName)
{
_icsConn.Rename(pszwNewName);
}
public void GetUiObjectClassId(out Guid pclsid)
{
_icsConn.GetUiObjectClassId(out pclsid);
}
public uint Characteristics => _icsMgr.NetConnectionProps[_icsConn].Characteristics;
public string DeviceName => _icsMgr.NetConnectionProps[_icsConn].DeviceName;
public string Guid => _icsMgr.NetConnectionProps[_icsConn].Guid;
public tagNETCON_MEDIATYPE MediaType => _icsMgr.NetConnectionProps[_icsConn].MediaType;
public string Name => _icsMgr.NetConnectionProps[_icsConn].Name;
public tagNETCON_STATUS Status => _icsMgr.NetConnectionProps[_icsConn].Status;
public INetSharingPortMapping AddPortMapping(string bstrName, byte ucIPProtocol, ushort usExternalPort,
ushort usInternalPort, uint dwOptions, string bstrTargetNameOrIPAddress, tagICS_TARGETTYPE eTargetType)
{
return _icsMgr.INetSharingConfigurationForINetConnection[_icsConn].AddPortMapping(bstrName,
ucIPProtocol, usExternalPort, usInternalPort, dwOptions, bstrTargetNameOrIPAddress, eTargetType);
}
public void DisableInternetFirewall() => _icsMgr.INetSharingConfigurationForINetConnection[_icsConn].DisableInternetFirewall();
public void DisableSharing()
{
_icsMgr.INetSharingConfigurationForINetConnection[_icsConn].DisableSharing();
}
public void EnableInternetFirewall()
{
_icsMgr.INetSharingConfigurationForINetConnection[_icsConn].EnableInternetFirewall();
}
public void EnableSharing(tagSHARINGCONNECTIONTYPE Type)
{
_icsMgr.INetSharingConfigurationForINetConnection[_icsConn].EnableSharing(Type);
}
public void RemovePortMapping(INetSharingPortMapping pMapping)
{
_icsMgr.INetSharingConfigurationForINetConnection[_icsConn].RemovePortMapping(pMapping);
}
public bool InternetFirewallEnabled =>
_icsMgr.INetSharingConfigurationForINetConnection[_icsConn]
.InternetFirewallEnabled;
public INetSharingPortMappingCollection get_EnumPortMappings(tagSHARINGCONNECTION_ENUM_FLAGS Flags)
{
return _icsMgr.INetSharingConfigurationForINetConnection[_icsConn]
.EnumPortMappings[Flags];
}
public tagSHARINGCONNECTIONTYPE SharingConnectionType =>
_icsMgr.INetSharingConfigurationForINetConnection[_icsConn].SharingConnectionType;
public bool SharingEnabled => _icsMgr.INetSharingConfigurationForINetConnection[_icsConn].SharingEnabled;
public INetSharingConfiguration NetSharingConfigurationForINetConnection()
{
return _icsMgr.INetSharingConfigurationForINetConnection[_icsConn];
}
}
}

View File

@@ -1,200 +0,0 @@
using System.Collections;
using System.Linq;
using NETCONLib;
namespace Netch.Models.WinFW
{
/// <summary>
/// A collection that stores 'NetworkConnection' objects.
/// </summary>
public class NetworkConnectionCollection : CollectionBase
{
/// <summary>
/// Initializes a new instance of 'NetworkConnectionCollection'.
/// </summary>
public NetworkConnectionCollection()
{
NetSharingManager icsMgr = new NetSharingManagerClass();
foreach (var icsConn in icsMgr.EnumEveryConnection.Cast<INetConnection>())
{
Add(new NetworkConnection(icsConn));
}
}
/// <summary>
/// Represents the 'NetworkConnection' item at the specified index position.
/// </summary>
/// <param name="intIndex">
/// The zero-based index of the entry to locate in the collection.
/// </param>
/// <value>
/// The entry at the specified index of the collection.
/// </value>
public NetworkConnection this[int intIndex]
{
get => (NetworkConnection) List[intIndex];
set => List[intIndex] = value;
}
/// <summary>
/// Adds a 'NetworkConnection' item with the specified value to the 'NetworkConnectionCollection'
/// </summary>
/// <param name="conValue">
/// The 'NetworkConnection' to add.
/// </param>
/// <returns>
/// The index at which the new element was inserted.
/// </returns>
public int Add(NetworkConnection conValue)
{
return List.Add(conValue);
}
/// <summary>
/// Copies the elements of an array at the end of this instance of 'NetworkConnectionCollection'.
/// </summary>
/// <param name="conValue">
/// An array of 'NetworkConnection' objects to add to the collection.
/// </param>
public void AddRange(NetworkConnection[] conValue)
{
checked
{
foreach (var t in conValue)
Add(t);
}
}
/// <summary>
/// Adds the contents of another 'NetworkConnectionCollection' at the end of this instance.
/// </summary>
/// <param name="conValue">
/// A 'NetworkConnectionCollection' containing the objects to add to the collection.
/// </param>
public void AddRange(NetworkConnectionCollection conValue)
{
checked
{
for (var intCounter = 0; intCounter < conValue.Count; intCounter++) Add(conValue[intCounter]);
}
}
/// <summary>
/// Gets a value indicating whether the 'NetworkConnectionCollection' contains the specified value.
/// </summary>
/// <param name="conValue">
/// The item to locate.
/// </param>
/// <returns>
/// True if the item exists in the collection; false otherwise.
/// </returns>
public bool Contains(NetworkConnection conValue)
{
return List.Contains(conValue);
}
/// <summary>
/// Copies the 'NetworkConnectionCollection' values to a one-dimensional System.Array
/// instance starting at the specified array index.
/// </summary>
/// <param name="conArray">
/// The one-dimensional System.Array that represents the copy destination.
/// </param>
/// <param name="intIndex">
/// The index in the array where copying begins.
/// </param>
public void CopyTo(NetworkConnection[] conArray, int intIndex)
{
List.CopyTo(conArray, intIndex);
}
/// <summary>
/// Returns the index of a 'NetworkConnection' object in the collection.
/// </summary>
/// <param name="conValue">
/// The 'NetworkConnection' object whose index will be retrieved.
/// </param>
/// <returns>
/// If found, the index of the value; otherwise, -1.
/// </returns>
public int IndexOf(NetworkConnection conValue)
{
return List.IndexOf(conValue);
}
/// <summary>
/// Inserts an existing 'NetworkConnection' into the collection at the specified index.
/// </summary>
/// <param name="intIndex">
/// The zero-based index where the new item should be inserted.
/// </param>
/// <param name="conValue">
/// The item to insert.
/// </param>
public void Insert(int intIndex, NetworkConnection conValue)
{
List.Insert(intIndex, conValue);
}
/// <summary>
/// Returns an enumerator that can be used to iterate through
/// the 'NetworkConnectionCollection'.
/// </summary>
public new ConnectionEnumerator GetEnumerator()
{
return new ConnectionEnumerator(this);
}
/// <summary>
/// Removes a specific item from the 'NetworkConnectionCollection'.
/// </summary>
/// <param name="conValue">
/// The item to remove from the 'NetworkConnectionCollection'.
/// </param>
public void Remove(NetworkConnection conValue)
{
List.Remove(conValue);
}
/// <summary>
/// A strongly typed enumerator for 'NetworkConnectionCollection'
/// </summary>
public class ConnectionEnumerator : IEnumerator
{
private readonly IEnumerator iEnBase;
private readonly IEnumerable iEnLocal;
/// <summary>
/// Enumerator constructor
/// </summary>
public ConnectionEnumerator(NetworkConnectionCollection conMappings)
{
iEnLocal = conMappings;
iEnBase = iEnLocal.GetEnumerator();
}
/// <summary>
/// Gets the current element from the collection
/// </summary>
public object Current => iEnBase.Current;
/// <summary>
/// Advances the enumerator to the next element of the collection
/// </summary>
public bool MoveNext()
{
return iEnBase.MoveNext();
}
/// <summary>
/// Sets the enumerator to the first element in the collection
/// </summary>
public void Reset()
{
iEnBase.Reset();
}
}
}
}

View File

@@ -1,209 +0,0 @@
using System;
using System.Management;
using Netch.Controllers;
using Netch.Models.WinFW;
using NETCONLib;
namespace Netch.Utils
{
public static class ICSHelper
{
public static bool? Enabled
{
get
{
AutoSearchTapAdapter();
if (Global.TUNTAP.Adapter == null)
return null;
foreach (NetworkConnection connection in new NetworkConnectionCollection())
{
try
{
if (connection.DeviceName == Global.TUNTAP.Adapter?.Description)
{
return connection.SharingEnabled;
}
}
catch (Exception e)
{
Logging.Warning(e.ToString());
}
}
return null;
}
}
private static void AutoSearchTapAdapter()
{
if (Global.TUNTAP.Adapter == null)
TUNTAPController.SearchTapAdapter();
}
public static bool Enable()
{
Utils.SearchOutboundAdapter(false);
AutoSearchTapAdapter();
if (Global.TUNTAP.Adapter == null || Global.Outbound.Adapter == null)
{
return false;
}
try
{
CleanupWMISharingEntries();
#region Save Outbound IP Config
bool dhcpEnabled;
string[] ipAddress = null;
string[] subnetMask = null;
string[] gateway = null;
ushort[] gatewayMetric = null;
string[] dns = null;
var outboundWmi = GetManagementObjectByDeviceNameOrDefault(Global.Outbound.Adapter.Description);
if (outboundWmi == null)
{
return false;
}
if (!(dhcpEnabled = (bool) outboundWmi["DHCPEnabled"]))
{
ipAddress = (string[]) outboundWmi["IPAddress"];
subnetMask = (string[]) outboundWmi["IPSubnet"];
gateway = (string[]) outboundWmi["DefaultIPGateway"];
gatewayMetric = (ushort[]) outboundWmi["GatewayCostMetric"];
dns = (string[]) outboundWmi["DNSServerSearchOrder"];
ipAddress = new[] {ipAddress[0]};
subnetMask = new[] {subnetMask[0]};
}
#endregion
#region Setting ICS
foreach (NetworkConnection connection in new NetworkConnectionCollection())
{
if (connection.DeviceName == Global.TUNTAP.Adapter.Description)
{
if (connection.SharingEnabled)
connection.DisableSharing();
connection.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PUBLIC);
}
else if (connection.DeviceName == Global.Outbound.Adapter.Description)
{
if (connection.SharingEnabled)
connection.DisableSharing();
connection.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PRIVATE);
}
}
#endregion
#region Reset Outbound IP Config
if (dhcpEnabled)
{
outboundWmi.InvokeMethod("EnableDHCP", null, null);
}
else
{
//Set static IP and subnet mask
var ip = outboundWmi.GetMethodParameters("EnableStatic");
ip["IPAddress"] = ipAddress;
ip["SubnetMask"] = subnetMask;
outboundWmi.InvokeMethod("EnableStatic", ip, null);
//Set default gateway
var newGateway = outboundWmi.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = gateway;
newGateway["GatewayCostMetric"] = gatewayMetric;
outboundWmi.InvokeMethod("SetGateways", newGateway, null);
//Set dns servers
var newDns = outboundWmi.GetMethodParameters("SetDNSServerSearchOrder");
newDns["DNSServerSearchOrder"] = dns;
outboundWmi.InvokeMethod("SetDNSServerSearchOrder", newDns, null);
}
#endregion
return true;
}
catch (Exception e)
{
try
{
Disable();
}
catch
{
// ignored
}
Logging.Error($"网络连接共享设置失败: {e}");
return false;
}
}
public static void Disable()
{
foreach (NetworkConnection connection in new NetworkConnectionCollection())
{
try
{
if (connection.SharingEnabled)
{
connection.DisableSharing();
}
}
catch (Exception e)
{
Logging.Warning(e.ToString());
}
}
CleanupWMISharingEntries();
}
private static void CleanupWMISharingEntries()
{
var scope = new ManagementScope("root\\Microsoft\\HomeNet");
scope.Connect();
var searchResults = new ManagementObjectSearcher(scope, new ObjectQuery("SELECT * FROM HNet_ConnectionProperties"));
foreach (var o in searchResults.Get())
{
var entry = (ManagementObject) o;
if ((bool) entry["IsIcsPrivate"])
entry["IsIcsPrivate"] = false;
if ((bool) entry["IsIcsPublic"])
entry["IsIcsPublic"] = false;
entry.Put(new PutOptions
{
Type = PutType.UpdateOnly
});
}
}
private static ManagementObject GetManagementObjectByDeviceNameOrDefault(string deviceName)
{
foreach (var o in new ManagementClass("Win32_NetworkAdapterConfiguration").GetInstances())
{
var mo = (ManagementObject) o;
if (((string) mo["Caption"]).EndsWith(deviceName))
{
return mo;
}
}
return null;
}
}
}