mirror of
https://github.com/snltty/linker.git
synced 2025-09-27 05:25:57 +08:00
应用层NAT
This commit is contained in:
@@ -28,6 +28,10 @@ for %%r in (win-x86,win-x64,win-arm64) do (
|
|||||||
echo F|xcopy "src\\linker\\msquic-%%r.dll" "public\\extends\\%%r\\linker-%%r\\msquic.dll" /s /f /h /y
|
echo F|xcopy "src\\linker\\msquic-%%r.dll" "public\\extends\\%%r\\linker-%%r\\msquic.dll" /s /f /h /y
|
||||||
echo F|xcopy "src\\linker\\msquic-openssl3-%%r.dll" "public\\extends\\%%r\\linker-%%r\\msquic-openssl.dll" /s /f /h /y
|
echo F|xcopy "src\\linker\\msquic-openssl3-%%r.dll" "public\\extends\\%%r\\linker-%%r\\msquic-openssl.dll" /s /f /h /y
|
||||||
echo F|xcopy "src\\linker\\wintun-%%r.dll" "public\\extends\\%%r\\linker-%%r\\wintun.dll" /s /f /h /y
|
echo F|xcopy "src\\linker\\wintun-%%r.dll" "public\\extends\\%%r\\linker-%%r\\wintun.dll" /s /f /h /y
|
||||||
|
|
||||||
|
echo F|xcopy "src\\linker\\WinDivert-%%r.dll" "public\\extends\\%%r\\linker-%%r\\WinDivert.dll" /s /f /h /y
|
||||||
|
echo F|xcopy "src\\linker\\WinDivert-%%r.sys" "public\\extends\\%%r\\linker-%%r\\WinDivert.sys" /s /f /h /y
|
||||||
|
echo F|xcopy "src\\linker\\WinDivert64-%%r.sys" "public\\extends\\%%r\\linker-%%r\\WinDivert64.sys" /s /f /h /y
|
||||||
)
|
)
|
||||||
|
|
||||||
msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-x64/linker-win-x64
|
msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-x64/linker-win-x64
|
||||||
|
@@ -106,7 +106,7 @@ namespace linker.app
|
|||||||
tuntapProxy.Callback = this;
|
tuntapProxy.Callback = this;
|
||||||
tuntapDecenter = LinkerMessengerEntry.GetService<TuntapDecenter>();
|
tuntapDecenter = LinkerMessengerEntry.GetService<TuntapDecenter>();
|
||||||
|
|
||||||
tuntapTransfer.Init(new LinkerVpnDevice(this), this);
|
tuntapTransfer.Initialize(new LinkerVpnDevice(this), this);
|
||||||
}
|
}
|
||||||
public override void OnCreate()
|
public override void OnCreate()
|
||||||
{
|
{
|
||||||
@@ -294,7 +294,7 @@ namespace linker.app
|
|||||||
this.vpnService = vpnService;
|
this.vpnService = vpnService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Setup(string name, IPAddress address, IPAddress gateway, byte prefixLength, out string error)
|
public bool Setup(string name, IPAddress address, byte prefixLength, out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
if (address.Equals(IPAddress.Any)) return false;
|
if (address.Equals(IPAddress.Any)) return false;
|
||||||
@@ -374,7 +374,11 @@ namespace linker.app
|
|||||||
public void SetMtu(int value)
|
public void SetMtu(int value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public void SetNat(out string error)
|
public void SetSystemNat(out string error)
|
||||||
|
{
|
||||||
|
error = string.Empty;
|
||||||
|
}
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items, out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
}
|
}
|
||||||
@@ -395,10 +399,10 @@ namespace linker.app
|
|||||||
return new List<LinkerTunDeviceForwardItem>();
|
return new List<LinkerTunDeviceForwardItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip)
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ips)
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public async Task<bool> CheckAvailable(bool order = false)
|
public async Task<bool> CheckAvailable(bool order = false)
|
||||||
|
@@ -1 +1 @@
|
|||||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.cfba5739.js"></script><script defer="defer" src="js/app.656481f7.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.3aab4747.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.cfba5739.js"></script><script defer="defer" src="js/app.644fc91c.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.3aab4747.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
1
src/linker.app/public/web/js/144.e46fa2ab.js
Normal file
1
src/linker.app/public/web/js/144.e46fa2ab.js
Normal file
File diff suppressed because one or more lines are too long
277
src/linker.app/public/web/js/89.3ea503b8.js
Normal file
277
src/linker.app/public/web/js/89.3ea503b8.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/app.644fc91c.js
Normal file
1
src/linker.app/public/web/js/app.644fc91c.js
Normal file
File diff suppressed because one or more lines are too long
@@ -315,6 +315,11 @@ namespace linker.libs
|
|||||||
{
|
{
|
||||||
return ToNetworkValue(ip, ToPrefixValue(prefixLength));
|
return ToNetworkValue(ip, ToPrefixValue(prefixLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static uint ToBroadcastValue(IPAddress ip, byte prefixLength)
|
||||||
|
{
|
||||||
|
return ToBroadcastValue(ToValue(ip), ToPrefixValue(prefixLength));
|
||||||
|
}
|
||||||
public static uint ToBroadcastValue(uint ip, uint prefixIP)
|
public static uint ToBroadcastValue(uint ip, uint prefixIP)
|
||||||
{
|
{
|
||||||
return ip | ~prefixIP;
|
return ip | ~prefixIP;
|
||||||
|
@@ -4,6 +4,7 @@ using linker.libs.timer;
|
|||||||
using linker.tunnel.connection;
|
using linker.tunnel.connection;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
|
||||||
namespace linker.messenger.store.file
|
namespace linker.messenger.store.file
|
||||||
{
|
{
|
||||||
@@ -14,7 +15,14 @@ namespace linker.messenger.store.file
|
|||||||
public sealed class Storefactory
|
public sealed class Storefactory
|
||||||
{
|
{
|
||||||
LiteDatabase database;
|
LiteDatabase database;
|
||||||
|
|
||||||
|
|
||||||
public Storefactory()
|
public Storefactory()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init()
|
||||||
{
|
{
|
||||||
BsonMapper bsonMapper = new BsonMapper();
|
BsonMapper bsonMapper = new BsonMapper();
|
||||||
bsonMapper.RegisterType<IPEndPoint>(serialize: (a) => a.ToString(), deserialize: (a) => IPEndPoint.Parse(a.AsString));
|
bsonMapper.RegisterType<IPEndPoint>(serialize: (a) => a.ToString(), deserialize: (a) => IPEndPoint.Parse(a.AsString));
|
||||||
@@ -24,12 +32,21 @@ namespace linker.messenger.store.file
|
|||||||
bsonMapper.RegisterType<IConnection>(serialize: (a) => string.Empty, deserialize: (a) => null);
|
bsonMapper.RegisterType<IConnection>(serialize: (a) => string.Empty, deserialize: (a) => null);
|
||||||
|
|
||||||
string db = Path.Join(Helper.currentDirectory, "./configs/db.db");
|
string db = Path.Join(Helper.currentDirectory, "./configs/db.db");
|
||||||
if(Directory.Exists(Path.GetDirectoryName(db)) == false)
|
if (Directory.Exists(Path.GetDirectoryName(db)) == false)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(db));
|
Directory.CreateDirectory(Path.GetDirectoryName(db));
|
||||||
}
|
}
|
||||||
|
|
||||||
database = new LiteDatabase(new ConnectionString($"Filename={db};Password={Helper.GlobalString}"), bsonMapper);
|
try
|
||||||
|
{
|
||||||
|
database = new LiteDatabase(new ConnectionString($"Filename={db};Password={Helper.GlobalString}"), bsonMapper);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LoggerHelper.Instance.Error(ex);
|
||||||
|
//让服务自动重启
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (OperatingSystem.IsAndroid() == false)
|
if (OperatingSystem.IsAndroid() == false)
|
||||||
{
|
{
|
||||||
|
@@ -5,7 +5,6 @@ using linker.messenger.exroute;
|
|||||||
using linker.messenger.signin;
|
using linker.messenger.signin;
|
||||||
using linker.tun;
|
using linker.tun;
|
||||||
using linker.tunnel.connection;
|
using linker.tunnel.connection;
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace linker.messenger.tuntap
|
namespace linker.messenger.tuntap
|
||||||
@@ -38,7 +37,7 @@ namespace linker.messenger.tuntap
|
|||||||
signInClientState.OnSignInSuccess += (times) => tuntapConfigTransfer.RefreshIP();
|
signInClientState.OnSignInSuccess += (times) => tuntapConfigTransfer.RefreshIP();
|
||||||
|
|
||||||
//初始化网卡
|
//初始化网卡
|
||||||
tuntapTransfer.Init(this);
|
tuntapTransfer.Initialize(this);
|
||||||
//网卡状态发生变化,同步一下信息
|
//网卡状态发生变化,同步一下信息
|
||||||
tuntapTransfer.OnSetupBefore += () =>
|
tuntapTransfer.OnSetupBefore += () =>
|
||||||
{
|
{
|
||||||
@@ -56,6 +55,7 @@ namespace linker.messenger.tuntap
|
|||||||
tuntapTransfer.OnSetupSuccess += () =>
|
tuntapTransfer.OnSetupSuccess += () =>
|
||||||
{
|
{
|
||||||
SetMaps();
|
SetMaps();
|
||||||
|
SetAppNat();
|
||||||
AddForward();
|
AddForward();
|
||||||
};
|
};
|
||||||
tuntapTransfer.OnShutdownBefore += () =>
|
tuntapTransfer.OnShutdownBefore += () =>
|
||||||
@@ -130,7 +130,6 @@ namespace linker.messenger.tuntap
|
|||||||
tuntapTransfer.Write(buffer);
|
tuntapTransfer.Write(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 重启网卡
|
/// 重启网卡
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -153,6 +152,9 @@ namespace linker.messenger.tuntap
|
|||||||
tuntapTransfer.Shutdown();
|
tuntapTransfer.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置映射
|
||||||
|
/// </summary>
|
||||||
private void SetMaps()
|
private void SetMaps()
|
||||||
{
|
{
|
||||||
var maps = tuntapConfigTransfer.Info.Lans
|
var maps = tuntapConfigTransfer.Info.Lans
|
||||||
@@ -160,6 +162,24 @@ namespace linker.messenger.tuntap
|
|||||||
.Select(c => new LanMapInfo { IP = c.IP, ToIP = c.MapIP, PrefixLength = c.MapPrefixLength }).ToArray();
|
.Select(c => new LanMapInfo { IP = c.IP, ToIP = c.MapIP, PrefixLength = c.MapPrefixLength }).ToArray();
|
||||||
tuntapTransfer.SetMap(maps);
|
tuntapTransfer.SetMap(maps);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 设置应用层NAT
|
||||||
|
/// </summary>
|
||||||
|
private void SetAppNat()
|
||||||
|
{
|
||||||
|
if (tuntapConfigTransfer.Info.DisableNat == false)
|
||||||
|
{
|
||||||
|
var nats = tuntapConfigTransfer.Info.Lans
|
||||||
|
.Where(c => c.IP != null && c.IP.Equals(IPAddress.Any) == false && c.MapIP != null && c.MapIP.Equals(IPAddress.Any) == false && c.Disabled == false)
|
||||||
|
.Select(c => new LinkerTunAppNatItemInfo
|
||||||
|
{
|
||||||
|
IP = c.MapIP.Equals(IPAddress.Any) ? c.IP : c.MapIP,
|
||||||
|
PrefixLength = c.MapIP.Equals(IPAddress.Any) ? c.PrefixLength : c.MapPrefixLength,
|
||||||
|
}).ToArray();
|
||||||
|
tuntapTransfer.SetAppNat(nats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// <summary>
|
// <summary>
|
||||||
/// 添加端口转发
|
/// 添加端口转发
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -101,9 +101,9 @@ namespace linker.messenger.tuntap
|
|||||||
|
|
||||||
var removeItems = routeItems.Except(_routeItems, new LinkerTunDeviceRouteItemComparer()).ToArray();
|
var removeItems = routeItems.Except(_routeItems, new LinkerTunDeviceRouteItemComparer()).ToArray();
|
||||||
if (removeItems.Length > 0)
|
if (removeItems.Length > 0)
|
||||||
tuntapTransfer.DelRoute(removeItems);
|
tuntapTransfer.RemoveRoute(removeItems);
|
||||||
|
|
||||||
tuntapTransfer.AddRoute(_routeItems, tuntapConfigTransfer.Info.IP);
|
tuntapTransfer.AddRoute(_routeItems);
|
||||||
|
|
||||||
tuntapProxy.SetIPs(ips);
|
tuntapProxy.SetIPs(ips);
|
||||||
foreach (var item in Infos.Values)
|
foreach (var item in Infos.Values)
|
||||||
@@ -120,7 +120,7 @@ namespace linker.messenger.tuntap
|
|||||||
private List<TuntapVeaLanIPAddressList> ParseIPs(List<TuntapInfo> infos)
|
private List<TuntapVeaLanIPAddressList> ParseIPs(List<TuntapInfo> infos)
|
||||||
{
|
{
|
||||||
//排除的IP,
|
//排除的IP,
|
||||||
uint[] excludeIps = exRouteTransfer.Get().Where(c=>c.Equals(IPAddress.Any)==false).Select(NetworkHelper.ToValue).Distinct().ToArray();
|
uint[] excludeIps = exRouteTransfer.Get().Where(c => c.Equals(IPAddress.Any) == false).Select(NetworkHelper.ToValue).Distinct().ToArray();
|
||||||
|
|
||||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
LoggerHelper.Instance.Warning($"tuntap route ex ips : {string.Join(",", excludeIps.Select(c => NetworkHelper.ToIP(c)).ToList())}");
|
LoggerHelper.Instance.Warning($"tuntap route ex ips : {string.Join(",", excludeIps.Select(c => NetworkHelper.ToIP(c)).ToList())}");
|
||||||
@@ -136,7 +136,7 @@ namespace linker.messenger.tuntap
|
|||||||
{
|
{
|
||||||
if (wan.Equals(c.Wan))
|
if (wan.Equals(c.Wan))
|
||||||
{
|
{
|
||||||
foreach (var item in c.Lans.Where(c=>c.MapIP==null || c.MapIP.Equals(IPAddress.Any)))
|
foreach (var item in c.Lans.Where(c => c.MapIP == null || c.MapIP.Equals(IPAddress.Any)))
|
||||||
{
|
{
|
||||||
item.Exists = true;
|
item.Exists = true;
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using linker.tun;
|
using linker.tun;
|
||||||
using linker.libs.timer;
|
using linker.libs.timer;
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
namespace linker.messenger.tuntap
|
namespace linker.messenger.tuntap
|
||||||
{
|
{
|
||||||
@@ -32,12 +31,12 @@ namespace linker.messenger.tuntap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init(ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
public void Initialize(ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.Initialize(linkerTunDeviceCallback);
|
linkerTunDeviceAdapter.Initialize(linkerTunDeviceCallback);
|
||||||
|
|
||||||
}
|
}
|
||||||
public void Init(ILinkerTunDevice linkerTunDevice, ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
public void Initialize(ILinkerTunDevice linkerTunDevice, ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.Initialize(linkerTunDevice, linkerTunDeviceCallback);
|
linkerTunDeviceAdapter.Initialize(linkerTunDevice, linkerTunDeviceCallback);
|
||||||
}
|
}
|
||||||
@@ -72,11 +71,14 @@ namespace linker.messenger.tuntap
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nat)
|
if (nat)
|
||||||
linkerTunDeviceAdapter.SetNat();
|
|
||||||
if (string.IsNullOrWhiteSpace(linkerTunDeviceAdapter.NatError) == false)
|
|
||||||
{
|
{
|
||||||
LoggerHelper.Instance.Error(linkerTunDeviceAdapter.NatError);
|
linkerTunDeviceAdapter.SetSystemNat();
|
||||||
|
if (string.IsNullOrWhiteSpace(linkerTunDeviceAdapter.NatError) == false)
|
||||||
|
{
|
||||||
|
LoggerHelper.Instance.Error(linkerTunDeviceAdapter.NatError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnSetupSuccess();
|
OnSetupSuccess();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -95,6 +97,35 @@ namespace linker.messenger.tuntap
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止网卡
|
||||||
|
/// </summary>
|
||||||
|
public void Shutdown(bool notify = true)
|
||||||
|
{
|
||||||
|
if (operatingManager.StartOperation() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (notify) OnShutdownBefore();
|
||||||
|
linkerTunDeviceAdapter.Shutdown();
|
||||||
|
if (notify) OnShutdownSuccess();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
{
|
||||||
|
LoggerHelper.Instance.Error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (notify)
|
||||||
|
OnShutdownAfter();
|
||||||
|
operatingManager.StopOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 刷新网卡
|
/// 刷新网卡
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,64 +154,64 @@ namespace linker.messenger.tuntap
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 停止网卡
|
/// 设置应用层NAT
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Shutdown(bool notify = true)
|
/// <param name="items"></param>
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items)
|
||||||
{
|
{
|
||||||
if (operatingManager.StartOperation() == false)
|
if (string.IsNullOrWhiteSpace(NatError) == false)
|
||||||
{
|
linkerTunDeviceAdapter.SetAppNat(items);
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (notify)
|
|
||||||
OnShutdownBefore();
|
|
||||||
linkerTunDeviceAdapter.Shutdown();
|
|
||||||
linkerTunDeviceAdapter.RemoveNat();
|
|
||||||
if (notify)
|
|
||||||
OnShutdownSuccess();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
|
||||||
{
|
|
||||||
LoggerHelper.Instance.Error(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (notify)
|
|
||||||
OnShutdownAfter();
|
|
||||||
operatingManager.StopOperation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加转发
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="forward"></param>
|
||||||
public void AddForward(List<LinkerTunDeviceForwardItem> forward)
|
public void AddForward(List<LinkerTunDeviceForwardItem> forward)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.AddForward(forward);
|
linkerTunDeviceAdapter.AddForward(forward);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 移除转发
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="forward"></param>
|
||||||
public void RemoveForward(List<LinkerTunDeviceForwardItem> forward)
|
public void RemoveForward(List<LinkerTunDeviceForwardItem> forward)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.RemoveForward(forward);
|
linkerTunDeviceAdapter.RemoveForward(forward);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip)
|
/// <summary>
|
||||||
|
/// 添加路由
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ips"></param>
|
||||||
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.AddRoute(ips, ip);
|
linkerTunDeviceAdapter.AddRoute(ips);
|
||||||
}
|
}
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ips)
|
/// <summary>
|
||||||
|
/// 移除路由
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ips"></param>
|
||||||
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.DelRoute(ips);
|
linkerTunDeviceAdapter.RemoveRoute(ips);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加映射
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="maps"></param>
|
||||||
public void SetMap(LanMapInfo[] maps)
|
public void SetMap(LanMapInfo[] maps)
|
||||||
{
|
{
|
||||||
linkerTunDeviceAdapter.SetMap(maps);
|
linkerTunDeviceAdapter.SetMap(maps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查网卡是否可用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="order"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task<bool> CheckAvailable(bool order = false)
|
public async Task<bool> CheckAvailable(bool order = false)
|
||||||
{
|
{
|
||||||
return await linkerTunDeviceAdapter.CheckAvailable(order).ConfigureAwait(false);
|
return await linkerTunDeviceAdapter.CheckAvailable(order).ConfigureAwait(false);
|
||||||
|
@@ -25,16 +25,18 @@ namespace linker.tun
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="address"></param>
|
/// <param name="address"></param>
|
||||||
/// <param name="gateway"></param>
|
|
||||||
/// <param name="prefixLength"></param>
|
/// <param name="prefixLength"></param>
|
||||||
/// <param name="error"></param>
|
/// <param name="error"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Setup(string name,IPAddress address, IPAddress gateway, byte prefixLength, out string error);
|
public bool Setup(string name,IPAddress address, byte prefixLength, out string error);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 关闭
|
/// 关闭
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Shutdown();
|
public void Shutdown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 刷新网卡
|
||||||
|
/// </summary>
|
||||||
public void Refresh();
|
public void Refresh();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -43,9 +45,14 @@ namespace linker.tun
|
|||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
public void SetMtu(int value);
|
public void SetMtu(int value);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置NAT转发
|
/// 设置系统NAT转发
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetNat(out string error);
|
public void SetSystemNat(out string error);
|
||||||
|
/// <summary>
|
||||||
|
/// 设置应用层NAT转发
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="error"></param>
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items, out string error);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 移除NAT转发
|
/// 移除NAT转发
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -72,15 +79,12 @@ namespace linker.tun
|
|||||||
/// 添加路由
|
/// 添加路由
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ips"></param>
|
/// <param name="ips"></param>
|
||||||
/// <param name="ip"></param>
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips);
|
||||||
/// <param name="gateway">是不是网关,是网关,将使用NAT转发,不是网关将添加路由</param>
|
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip);
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除路由
|
/// 删除路由
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ip"></param>
|
/// <param name="ips"></param>
|
||||||
/// <param name="gateway">是不是网关,是网关,将删除NAT转发,不是网关将删除路由</param>
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips);
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ip);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取数据包
|
/// 读取数据包
|
||||||
@@ -260,4 +264,10 @@ namespace linker.tun
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Running = 2
|
Running = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class LinkerTunAppNatItemInfo
|
||||||
|
{
|
||||||
|
public IPAddress IP { get; set; }
|
||||||
|
public byte PrefixLength { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ namespace linker.tun
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Setup(string name, IPAddress address, IPAddress gateway, byte prefixLength, out string error)
|
public bool Setup(string name, IPAddress address, byte prefixLength, out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ namespace linker.tun
|
|||||||
{
|
{
|
||||||
return CommandHelper.Linux(string.Empty, ["ip route show default | awk '{print $5}'"]);
|
return CommandHelper.Linux(string.Empty, ["ip route show default | awk '{print $5}'"]);
|
||||||
}
|
}
|
||||||
public void SetNat(out string error)
|
public void SetSystemNat(out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
if (address == null || address.Equals(IPAddress.Any)) return;
|
if (address == null || address.Equals(IPAddress.Any)) return;
|
||||||
@@ -182,6 +182,10 @@ namespace linker.tun
|
|||||||
error = ex.Message;
|
error = ex.Message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items,out string error)
|
||||||
|
{
|
||||||
|
error = string.Empty;
|
||||||
|
}
|
||||||
public void RemoveNat(out string error)
|
public void RemoveNat(out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
@@ -275,14 +279,14 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip)
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
string[] commands = ips.Select(item =>
|
string[] commands = ips.Select(item =>
|
||||||
{
|
{
|
||||||
uint prefixValue = NetworkHelper.ToPrefixValue(item.PrefixLength);
|
uint prefixValue = NetworkHelper.ToPrefixValue(item.PrefixLength);
|
||||||
IPAddress network = NetworkHelper.ToNetworkIP(item.Address, prefixValue);
|
IPAddress network = NetworkHelper.ToNetworkIP(item.Address, prefixValue);
|
||||||
|
|
||||||
return $"ip route add {network}/{item.PrefixLength} via {ip} dev {Name} metric 1 ";
|
return $"ip route add {network}/{item.PrefixLength} via {address} dev {Name} metric 1 ";
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
if (commands.Length > 0)
|
if (commands.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -291,7 +295,7 @@ namespace linker.tun
|
|||||||
CommandHelper.Linux(string.Empty, commands);
|
CommandHelper.Linux(string.Empty, commands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ip)
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ip)
|
||||||
{
|
{
|
||||||
string[] commands = ip.Select(item =>
|
string[] commands = ip.Select(item =>
|
||||||
{
|
{
|
||||||
|
@@ -25,7 +25,7 @@ namespace linker.tun
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Setup(string name, IPAddress address, IPAddress gateway, byte prefixLength, out string error)
|
public bool Setup(string name, IPAddress address, byte prefixLength, out string error)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
@@ -65,21 +65,21 @@ namespace linker.tun
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip)
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
string[] commands = ips.Select(item =>
|
string[] commands = ips.Select(item =>
|
||||||
{
|
{
|
||||||
IPAddress _ip = NetworkHelper.ToNetworkIP(item.Address, item.PrefixLength);
|
IPAddress _ip = NetworkHelper.ToNetworkIP(item.Address, item.PrefixLength);
|
||||||
return $"route add -net {_ip}/{item.PrefixLength} {ip}";
|
return $"route add -net {_ip}/{item.PrefixLength} {address}";
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
if (commands.Length > 0)
|
if (commands.Length > 0)
|
||||||
{
|
{
|
||||||
CommandHelper.Osx(string.Empty, commands.ToArray());
|
CommandHelper.Osx(string.Empty, commands.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ip)
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
string[] commands = ip.Select(item =>
|
string[] commands = ips.Select(item =>
|
||||||
{
|
{
|
||||||
IPAddress _ip = NetworkHelper.ToNetworkIP(item.Address, item.PrefixLength);
|
IPAddress _ip = NetworkHelper.ToNetworkIP(item.Address, item.PrefixLength);
|
||||||
return $"route delete -net {_ip}/{item.PrefixLength}";
|
return $"route delete -net {_ip}/{item.PrefixLength}";
|
||||||
@@ -95,7 +95,7 @@ namespace linker.tun
|
|||||||
CommandHelper.Osx(string.Empty, new string[] { $"ifconfig {Name} mtu {value}" });
|
CommandHelper.Osx(string.Empty, new string[] { $"ifconfig {Name} mtu {value}" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetNat(out string error)
|
public void SetSystemNat(out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
/*
|
/*
|
||||||
@@ -113,6 +113,10 @@ namespace linker.tun
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items, out string error)
|
||||||
|
{
|
||||||
|
error = string.Empty;
|
||||||
|
}
|
||||||
public void RemoveNat(out string error)
|
public void RemoveNat(out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
|
@@ -77,6 +77,12 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="linkerTunDevice">网卡实现</param>
|
||||||
|
/// <param name="linkerTunDeviceCallback">读取数据回调</param>
|
||||||
|
/// <returns></returns>
|
||||||
public bool Initialize(ILinkerTunDevice linkerTunDevice, ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
public bool Initialize(ILinkerTunDevice linkerTunDevice, ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
||||||
{
|
{
|
||||||
this.linkerTunDevice = linkerTunDevice;
|
this.linkerTunDevice = linkerTunDevice;
|
||||||
@@ -105,7 +111,7 @@ namespace linker.tun
|
|||||||
setupError = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} not support";
|
setupError = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} not support";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
linkerTunDevice.Setup(deviceName, address, NetworkHelper.ToGatewayIP(address, prefixLength), prefixLength, out setupError);
|
linkerTunDevice.Setup(deviceName, address, prefixLength, out setupError);
|
||||||
if (string.IsNullOrWhiteSpace(setupError) == false)
|
if (string.IsNullOrWhiteSpace(setupError) == false)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -126,7 +132,6 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 关闭网卡
|
/// 关闭网卡
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -141,6 +146,7 @@ namespace linker.tun
|
|||||||
{
|
{
|
||||||
cancellationTokenSource?.Cancel();
|
cancellationTokenSource?.Cancel();
|
||||||
linkerTunDevice?.Shutdown();
|
linkerTunDevice?.Shutdown();
|
||||||
|
linkerTunDevice?.RemoveNat(out string error);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@@ -152,8 +158,6 @@ namespace linker.tun
|
|||||||
setupError = string.Empty;
|
setupError = string.Empty;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 刷新网卡
|
/// 刷新网卡
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -163,19 +167,26 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加NAT转发,这会将来到本网卡且目标IP不是本网卡IP的包转发到其它网卡
|
/// 设置系统层NAT
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetNat()
|
public void SetSystemNat()
|
||||||
{
|
{
|
||||||
linkerTunDevice?.RemoveNat(out string error);
|
linkerTunDevice?.SetSystemNat(out natError);
|
||||||
linkerTunDevice?.SetNat(out natError);
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 移除NAT转发
|
/// 设置应用层NAT
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="items"></param>
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items)
|
||||||
|
{
|
||||||
|
linkerTunDevice?.SetAppNat(items, out natError);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 移除NAT
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RemoveNat()
|
public void RemoveNat()
|
||||||
{
|
{
|
||||||
linkerTunDevice?.RemoveNat(out string error);
|
linkerTunDevice.RemoveNat(out string error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -208,17 +219,17 @@ namespace linker.tun
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ips"></param>
|
/// <param name="ips"></param>
|
||||||
/// <param name="ip"></param>
|
/// <param name="ip"></param>
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip)
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
linkerTunDevice?.AddRoute(ips, ip);
|
linkerTunDevice?.AddRoute(ips);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除路由
|
/// 删除路由
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ips"></param>
|
/// <param name="ips"></param>
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ips)
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
linkerTunDevice?.DelRoute(ips);
|
linkerTunDevice?.RemoveRoute(ips);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -262,7 +273,7 @@ namespace linker.tun
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer"></param>
|
/// <param name="buffer"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public unsafe bool Write(ReadOnlyMemory<byte> buffer)
|
public bool Write(ReadOnlyMemory<byte> buffer)
|
||||||
{
|
{
|
||||||
if (linkerTunDevice != null && Status == LinkerTunDeviceStatus.Running)
|
if (linkerTunDevice != null && Status == LinkerTunDeviceStatus.Running)
|
||||||
{
|
{
|
||||||
@@ -272,6 +283,40 @@ namespace linker.tun
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ToMapIP(ReadOnlyMemory<byte> buffer)
|
||||||
|
{
|
||||||
|
//只支持映射IPV4
|
||||||
|
if ((byte)(buffer.Span[0] >> 4 & 0b1111) != 4) return;
|
||||||
|
//映射表不为空
|
||||||
|
if (natDic.IsEmpty) return;
|
||||||
|
|
||||||
|
uint realDist = NetworkHelper.ToValue(buffer.Span.Slice(12, 4));
|
||||||
|
if (natDic.TryGetValue(realDist, out uint fakeDist))
|
||||||
|
{
|
||||||
|
ReWriteIP(buffer, BinaryPrimitives.ReverseEndianness(fakeDist), 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void MapToRealIP(ReadOnlyMemory<byte> buffer)
|
||||||
|
{
|
||||||
|
//只支持映射IPV4
|
||||||
|
if ((byte)(buffer.Span[0] >> 4 & 0b1111) != 4) return;
|
||||||
|
//映射表不为空
|
||||||
|
if (masks.Length == 0 || mapDic.Count == 0) return;
|
||||||
|
|
||||||
|
uint fakeDist = NetworkHelper.ToValue(buffer.Span.Slice(16, 4));
|
||||||
|
for (int i = 0; i < masks.Length; i++)
|
||||||
|
{
|
||||||
|
//目标IP网络号存在映射表中,找到映射后的真实网络号,替换网络号得到最终真实的IP
|
||||||
|
if (mapDic.TryGetValue(fakeDist & masks[i], out uint realNetwork))
|
||||||
|
{
|
||||||
|
uint realDist = realNetwork | (fakeDist & ~masks[i]);
|
||||||
|
ReWriteIP(buffer, BinaryPrimitives.ReverseEndianness(realDist), 16);
|
||||||
|
natDic.AddOrUpdate(realDist, fakeDist, (a, b) => fakeDist);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private unsafe void ReWriteIP(ReadOnlyMemory<byte> buffer, uint newIP, int pos)
|
private unsafe void ReWriteIP(ReadOnlyMemory<byte> buffer, uint newIP, int pos)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = buffer.Span)
|
fixed (byte* ptr = buffer.Span)
|
||||||
@@ -306,39 +351,6 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void ToMapIP(ReadOnlyMemory<byte> buffer)
|
|
||||||
{
|
|
||||||
//只支持映射IPV4
|
|
||||||
if ((byte)(buffer.Span[0] >> 4 & 0b1111) != 4) return;
|
|
||||||
//映射表不为空
|
|
||||||
if (natDic.IsEmpty) return;
|
|
||||||
|
|
||||||
uint realDist = NetworkHelper.ToValue(buffer.Span.Slice(12, 4));
|
|
||||||
if (natDic.TryGetValue(realDist, out uint fakeDist))
|
|
||||||
{
|
|
||||||
ReWriteIP(buffer, BinaryPrimitives.ReverseEndianness( fakeDist), 12);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void MapToRealIP(ReadOnlyMemory<byte> buffer)
|
|
||||||
{
|
|
||||||
//只支持映射IPV4
|
|
||||||
if ((byte)(buffer.Span[0] >> 4 & 0b1111) != 4) return;
|
|
||||||
//映射表不为空
|
|
||||||
if (masks.Length == 0 || mapDic.Count == 0) return;
|
|
||||||
|
|
||||||
uint fakeDist = NetworkHelper.ToValue(buffer.Span.Slice(16, 4));
|
|
||||||
for (int i = 0; i < masks.Length; i++)
|
|
||||||
{
|
|
||||||
//目标IP网络号存在映射表中,找到映射后的真实网络号,替换网络号得到最终真实的IP
|
|
||||||
if (mapDic.TryGetValue(fakeDist & masks[i], out uint realNetwork))
|
|
||||||
{
|
|
||||||
uint realDist = realNetwork | (fakeDist & ~masks[i]);
|
|
||||||
ReWriteIP(buffer, BinaryPrimitives.ReverseEndianness(realDist), 16);
|
|
||||||
natDic.AddOrUpdate(realDist, fakeDist, (a, b) => fakeDist);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置IP映射列表
|
/// 设置IP映射列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -397,7 +409,6 @@ namespace linker.tun
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<bool> CheckAvailable(bool order = false)
|
public async Task<bool> CheckAvailable(bool order = false)
|
||||||
{
|
{
|
||||||
return await linkerTunDevice.CheckAvailable(order);
|
return await linkerTunDevice.CheckAvailable(order);
|
||||||
|
@@ -27,14 +27,13 @@ namespace linker.tun
|
|||||||
|
|
||||||
private CancellationTokenSource tokenSource;
|
private CancellationTokenSource tokenSource;
|
||||||
|
|
||||||
private WinDivert winDivert;
|
private WinDivertNAT winDivertNAT;
|
||||||
|
|
||||||
public LinkerWinTunDevice()
|
public LinkerWinTunDevice()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool Setup(string name, IPAddress address, IPAddress gateway, byte prefixLength, out string error)
|
public bool Setup(string name, IPAddress address, byte prefixLength, out string error)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
@@ -184,9 +183,9 @@ namespace linker.tun
|
|||||||
$"netsh interface ipv6 set subinterface {interfaceNumber} mtu={value} store=persistent"
|
$"netsh interface ipv6 set subinterface {interfaceNumber} mtu={value} store=persistent"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void SetNat(out string error)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
public void SetSystemNat(out string error)
|
||||||
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
|
|
||||||
if (address == null || address.Equals(IPAddress.Any)) return;
|
if (address == null || address.Equals(IPAddress.Any)) return;
|
||||||
@@ -194,31 +193,33 @@ namespace linker.tun
|
|||||||
{
|
{
|
||||||
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
||||||
CommandHelper.PowerShell($"Install-WindowsFeature -Name Routing -IncludeManagementTools", [], out error);
|
CommandHelper.PowerShell($"Install-WindowsFeature -Name Routing -IncludeManagementTools", [], out error);
|
||||||
|
CommandHelper.PowerShell($"Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All", [], out error);
|
||||||
CommandHelper.PowerShell($"Set-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\" -Name \"IPEnableRouter\" -Value 1", [], out error);
|
CommandHelper.PowerShell($"Set-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\" -Name \"IPEnableRouter\" -Value 1", [], out error);
|
||||||
|
|
||||||
IPAddress network = NetworkHelper.ToNetworkIP(this.address, NetworkHelper.ToPrefixValue(prefixLength));
|
IPAddress network = NetworkHelper.ToNetworkIP(this.address, NetworkHelper.ToPrefixValue(prefixLength));
|
||||||
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
||||||
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error);
|
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(error))
|
string result = CommandHelper.PowerShell($"Get-NetNat", [], out error);
|
||||||
|
if (string.IsNullOrWhiteSpace(result) == false && result.Contains($"{network}/{prefixLength}"))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
error = $"NetNat and ICS not supported,{error}";
|
||||||
CommandHelper.Windows(string.Empty, [$"net start SharedAccess"]);
|
|
||||||
string result = CommandHelper.Windows(string.Empty, [$"linker.ics.exe {defaultInterfaceName} {Name} enable"]);
|
|
||||||
if (result.Contains($"enable success"))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
error = "NetNat and ICS not supported";
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
error = ex.Message;
|
error = ex.Message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void SetAppNat(LinkerTunAppNatItemInfo[] items, out string error)
|
||||||
|
{
|
||||||
|
error = string.Empty;
|
||||||
|
|
||||||
|
winDivertNAT?.Dispose();
|
||||||
|
winDivertNAT = new WinDivertNAT(new WinDivertNAT.AddrInfo(address, prefixLength), items.Select(c => new WinDivertNAT.AddrInfo(c.IP, c.PrefixLength)).ToArray());
|
||||||
|
//winDivertNAT.Setup();
|
||||||
|
}
|
||||||
public void RemoveNat(out string error)
|
public void RemoveNat(out string error)
|
||||||
{
|
{
|
||||||
error = string.Empty;
|
error = string.Empty;
|
||||||
@@ -228,12 +229,19 @@ namespace linker.tun
|
|||||||
{
|
{
|
||||||
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
||||||
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
||||||
//CommandHelper.Windows(string.Empty, [$"linker.ics.exe {defaultInterfaceName} {Name} disable"]);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
error = ex.Message;
|
error = ex.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
winDivertNAT?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -271,7 +279,7 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip)
|
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
if (interfaceNumber > 0)
|
if (interfaceNumber > 0)
|
||||||
{
|
{
|
||||||
@@ -281,7 +289,7 @@ namespace linker.tun
|
|||||||
IPAddress mask = NetworkHelper.ToIP(maskValue);
|
IPAddress mask = NetworkHelper.ToIP(maskValue);
|
||||||
IPAddress _ip = NetworkHelper.ToNetworkIP(item.Address, maskValue);
|
IPAddress _ip = NetworkHelper.ToNetworkIP(item.Address, maskValue);
|
||||||
|
|
||||||
return $"route add {_ip} mask {mask} {ip} metric 5 if {interfaceNumber}";
|
return $"route add {_ip} mask {mask} {address} metric 5 if {interfaceNumber}";
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
if (commands.Length > 0)
|
if (commands.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -291,9 +299,9 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void DelRoute(LinkerTunDeviceRouteItem[] ip)
|
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips)
|
||||||
{
|
{
|
||||||
string[] commands = ip.Select(item =>
|
string[] commands = ips.Select(item =>
|
||||||
{
|
{
|
||||||
uint maskValue = NetworkHelper.ToPrefixValue(item.PrefixLength);
|
uint maskValue = NetworkHelper.ToPrefixValue(item.PrefixLength);
|
||||||
IPAddress mask = NetworkHelper.ToIP(maskValue);
|
IPAddress mask = NetworkHelper.ToIP(maskValue);
|
||||||
|
@@ -1,23 +1,40 @@
|
|||||||
using System;
|
using linker.libs;
|
||||||
using System.Collections.Generic;
|
using linker.libs.timer;
|
||||||
using System.Linq;
|
using System.Buffers.Binary;
|
||||||
using System.Runtime.InteropServices;
|
using System.Collections.Frozen;
|
||||||
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using static linker.libs.winapis.SECUR32;
|
|
||||||
using static System.Collections.Specialized.BitVector32;
|
|
||||||
|
|
||||||
namespace linker.tun
|
namespace linker.tun
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用层NAT
|
/// 应用层NAT
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed class WinDivertNAT
|
public sealed class WinDivertNAT
|
||||||
{
|
{
|
||||||
public WinDivertNAT()
|
WinDivert winDivert;
|
||||||
|
AddrInfo src;
|
||||||
|
AddrInfo[] dsts;
|
||||||
|
|
||||||
|
NetworkIPv4Addr srcAddr;
|
||||||
|
|
||||||
|
//网络号对应网卡IP,用来替换源IP
|
||||||
|
private FrozenDictionary<uint, NetworkIPv4Addr> sourceDic = new Dictionary<uint, NetworkIPv4Addr>().ToFrozenDictionary();
|
||||||
|
public WinDivertNAT(AddrInfo src, AddrInfo[] dsts)
|
||||||
{
|
{
|
||||||
/*
|
this.src = src;
|
||||||
winDivert = new WinDivert("inbound and (( ip.SrcAddr == 10.18.18.0/24 and ip.DstAddr == 192.168.56.0/24) or ( ip.SrcAddr == 192.168.56.0/24))", WinDivert.Layer.Network, 0, WinDivert.Flag.Sniff);
|
this.dsts = dsts;
|
||||||
|
InitializeInterfaceIP();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
srcAddr = IPv4Addr.Parse(src.IP.ToString());
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder("inbound");
|
||||||
|
sb.Append($" and (ip.SrcAddr >= {src.NetworkIP} and ip.SrcAddr <= {src.BroadcastIP})");
|
||||||
|
|
||||||
|
winDivert = new WinDivert(sb.ToString(), WinDivert.Layer.Network, 0, WinDivert.Flag.Sniff);
|
||||||
var packet = new Memory<byte>(new byte[WinDivert.MTUMax]);
|
var packet = new Memory<byte>(new byte[WinDivert.MTUMax]);
|
||||||
var abuf = new Memory<WinDivertAddress>(new WinDivertAddress[1]);
|
var abuf = new Memory<WinDivertAddress>(new WinDivertAddress[1]);
|
||||||
TimerHelper.Async(() =>
|
TimerHelper.Async(() =>
|
||||||
@@ -45,16 +62,15 @@ namespace linker.tun
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
// NetworkIPv4Addr sourceAddr = IPv4Addr.Parse("10.18.18.23");
|
|
||||||
private unsafe void ModifyPacket(WinDivertParseResult p, ref WinDivertAddress addr)
|
private unsafe void ModifyPacket(WinDivertParseResult p, ref WinDivertAddress addr)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
if (p.IPv4Hdr->SrcAddr == sourceAddr)
|
if (NetworkHelper.ToNetworkValue(BinaryPrimitives.ReverseEndianness(p.IPv4Hdr->SrcAddr.Raw), src.PrefixValue) == src.NetworkValue)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{p.IPv4Hdr->SrcAddr}->{p.IPv4Hdr->DstAddr}");
|
Console.WriteLine($"{p.IPv4Hdr->SrcAddr}->{p.IPv4Hdr->DstAddr}================================");
|
||||||
}*/
|
}
|
||||||
//WinDivert.CalcChecksums(p.Packet.Span, ref addr, 0);
|
//WinDivert.CalcChecksums(p.Packet.Span, ref addr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,5 +95,43 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitializeInterfaceIP()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
winDivert?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class AddrInfo
|
||||||
|
{
|
||||||
|
public AddrInfo(IPAddress ip, byte prefixLength)
|
||||||
|
{
|
||||||
|
IP = ip;
|
||||||
|
PrefixLength = prefixLength;
|
||||||
|
|
||||||
|
PrefixValue = NetworkHelper.ToPrefixValue(PrefixLength);
|
||||||
|
NetworkValue = NetworkHelper.ToNetworkValue(IP, PrefixLength);
|
||||||
|
BroadcastValue = NetworkHelper.ToBroadcastValue(IP, PrefixLength);
|
||||||
|
|
||||||
|
NetworkAddr = IPv4Addr.Parse(NetworkHelper.ToIP(NetworkValue).ToString());
|
||||||
|
|
||||||
|
NetworkIP = NetworkHelper.ToIP(NetworkValue);
|
||||||
|
BroadcastIP = NetworkHelper.ToIP(BroadcastValue);
|
||||||
|
}
|
||||||
|
public IPAddress IP { get; }
|
||||||
|
public byte PrefixLength { get; }
|
||||||
|
|
||||||
|
public NetworkIPv4Addr NetworkAddr { get; private set; }
|
||||||
|
public uint PrefixValue { get; private set; }
|
||||||
|
public uint NetworkValue { get; private set; }
|
||||||
|
public uint BroadcastValue { get; private set; }
|
||||||
|
|
||||||
|
public IPAddress NetworkIP { get; private set; }
|
||||||
|
public IPAddress BroadcastIP { get; private set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,6 @@
|
|||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using linker.messenger.entry;
|
using linker.messenger.entry;
|
||||||
using linker.libs.extends;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace linker
|
namespace linker
|
||||||
{
|
{
|
||||||
|
BIN
src/linker/WinDivert64-win-x86.sys
Normal file
BIN
src/linker/WinDivert64-win-x86.sys
Normal file
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
v1.7.3
|
v1.7.3
|
||||||
2025-04-17 12:00:54
|
2025-04-18 00:45:38
|
||||||
1. 优化自动分配IP
|
1. 优化自动分配IP
|
||||||
2. 优化网卡,排除不明数据包
|
2. 优化网卡,排除不明数据包
|
||||||
3. 虚拟网卡点对网IP映射,用于解决网段冲突
|
3. 虚拟网卡点对网IP映射,用于解决网段冲突
|
Reference in New Issue
Block a user