Files
linker/src/linker.tun/ILinkerTunDevice.cs
snltty 06f3ee4256 177
2025-05-06 14:14:16 +08:00

292 lines
8.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using linker.libs.extends;
using System.Buffers.Binary;
using System.Net;
using System.Net.Sockets;
using System.Text.Json.Serialization;
namespace linker.tun
{
/// <summary>
/// 设备接口
/// </summary>
public interface ILinkerTunDevice
{
/// <summary>
/// 设备名
/// </summary>
public string Name { get; }
/// <summary>
/// 是否正在运行
/// </summary>
public bool Running { get; }
/// <summary>
/// 启动
/// </summary>
/// <param name="name"></param>
/// <param name="address"></param>
/// <param name="prefixLength"></param>
/// <param name="error"></param>
/// <returns></returns>
public bool Setup(string name,IPAddress address, byte prefixLength, out string error);
/// <summary>
/// 关闭
/// </summary>
public void Shutdown();
/// <summary>
/// 刷新网卡
/// </summary>
public void Refresh();
/// <summary>
/// 设置MTU
/// </summary>
/// <param name="value"></param>
public void SetMtu(int value);
/// <summary>
/// 设置系统NAT转发
/// </summary>
public void SetNat(out string error);
/// <summary>
/// 移除NAT转发
/// </summary>
public void RemoveNat(out string error);
/// <summary>
/// 获取端口转发
/// </summary>
/// <returns></returns>
public List<LinkerTunDeviceForwardItem> GetForward();
/// <summary>
/// 添加端口转发
/// </summary>
/// <param name="forwards"></param>
public void AddForward(List<LinkerTunDeviceForwardItem> forwards);
/// <summary>
/// 删除端口转发
/// </summary>
/// <param name="forwards"></param>
public void RemoveForward(List<LinkerTunDeviceForwardItem> forwards);
/// <summary>
/// 添加路由
/// </summary>
/// <param name="ips"></param>
public void AddRoute(LinkerTunDeviceRouteItem[] ips);
/// <summary>
/// 删除路由
/// </summary>
/// <param name="ips"></param>
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips);
/// <summary>
/// 读取数据包
/// </summary>
/// <returns></returns>
public byte[] Read(out int length);
/// <summary>
/// 写入数据包
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public bool Write(ReadOnlyMemory<byte> buffer);
/// <summary>
/// 检查网卡是否可用
/// </summary>
/// <returns></returns>
public Task<bool> CheckAvailable(bool order = false);
}
/// <summary>
/// 网卡读取数据回调
/// </summary>
public interface ILinkerTunDeviceCallback
{
/// <summary>
/// 回调
/// </summary>
/// <param name="packet"></param>
/// <returns></returns>
public Task Callback(LinkerTunDevicPacket packet);
}
/// <summary>
/// 数据包钩子
/// </summary>
public interface ILinkerTunPacketHook
{
/// <summary>
/// 从网卡读取到数据包后
/// </summary>
/// <param name="packet"></param>
/// <returns></returns>
public bool ReadAfter(ReadOnlyMemory<byte> packet);
/// <summary>
/// 写入网卡前
/// </summary>
/// <param name="packet"></param>
/// <returns></returns>
public bool WriteBefore(ReadOnlyMemory<byte> packet);
}
/// <summary>
/// 网卡端口转发
/// </summary>
public sealed class LinkerTunDeviceForwardItem
{
public IPAddress ListenAddr { get; set; } = IPAddress.Any;
public int ListenPort { get; set; }
public IPAddress ConnectAddr { get; set; } = IPAddress.Any;
public int ConnectPort { get; set; }
[JsonIgnore]
public bool Enable => ListenPort > 0 && ConnectAddr.Equals(IPAddress.Any) == false && ConnectPort > 0;
public string Key => $"{ListenAddr}:{ListenPort}->{ConnectAddr}:{ConnectPort}";
}
public sealed class LinkerTunDeviceForwardItemComparer : IEqualityComparer<LinkerTunDeviceForwardItem>
{
public bool Equals(LinkerTunDeviceForwardItem x, LinkerTunDeviceForwardItem y)
{
return x.ListenPort == y.ListenPort && x.ConnectAddr.Equals(y.ConnectAddr) && x.ConnectPort == y.ConnectPort;
}
public int GetHashCode(LinkerTunDeviceForwardItem obj)
{
return obj.ListenPort.GetHashCode() ^ obj.ConnectAddr.GetHashCode() ^ obj.ConnectPort;
}
}
/// <summary>
/// 数据包
/// </summary>
public struct LinkerTunDevicPacket
{
public byte[] Buffer;
public int Offset;
public int Length;
/// <summary>
/// 协议版本4或者6
/// </summary>
public byte Version;
/// <summary>
/// 协议
/// </summary>
public ProtocolType ProtocolType;
/// <summary>
/// 源IP
/// </summary>
public ReadOnlyMemory<byte> SourceIPAddress;
/// <summary>
/// 源端口
/// </summary>
public ushort SourcePort;
/// <summary>
/// 源
/// </summary>
public readonly IPEndPoint Source => new IPEndPoint(new IPAddress(SourceIPAddress.Span), SourcePort);
/// <summary>
/// 目标IP
/// </summary>
public ReadOnlyMemory<byte> DistIPAddress;
/// <summary>
/// 目标端口
/// </summary>
public ushort DistPort;
/// <summary>
/// 目标
/// </summary>
public readonly IPEndPoint Dist => new IPEndPoint(new IPAddress(DistIPAddress.Span), DistPort);
public readonly bool IPV4Broadcast => Version == 4 && DistIPAddress.GetIsBroadcastAddress();
public readonly bool IPV6Multicast => Version == 6 && (DistIPAddress.Span[0] & 0xFF) == 0xFF;
public LinkerTunDevicPacket(byte[] buffer, int offset, int length)
{
Unpacket(buffer, offset, length);
}
private void Unpacket(byte[] buffer,int offset,int length)
{
Buffer = buffer;
Offset = offset;
Length = length;
ReadOnlyMemory<byte> packet = buffer;
ReadOnlyMemory<byte> ipPacket = packet.Slice(4);
Version = (byte)(ipPacket.Span[0] >> 4 & 0b1111);
if (Version == 4)
{
SourceIPAddress = ipPacket.Slice(12, 4);
DistIPAddress = ipPacket.Slice(16, 4);
ProtocolType = (ProtocolType)ipPacket.Span[9];
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
{
SourcePort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(20, 2).ToUInt16());
DistPort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(22, 2).ToUInt16());
}
}
else if (Version == 6)
{
SourceIPAddress = ipPacket.Slice(8, 16);
DistIPAddress = ipPacket.Slice(24, 16);
ProtocolType = (ProtocolType)ipPacket.Span[6];
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
{
SourcePort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(42, 2).ToUInt16());
DistPort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(24, 2).ToUInt16());
}
}
}
}
/// <summary>
/// 添加路由项
/// </summary>
public sealed class LinkerTunDeviceRouteItem
{
/// <summary>
/// IP
/// </summary>
public IPAddress Address { get; set; }
/// <summary>
/// 掩码
/// </summary>
public byte PrefixLength { get; set; }
}
/// <summary>
/// 设备状态
/// </summary>
public enum LinkerTunDeviceStatus
{
/// <summary>
/// 无
/// </summary>
Normal = 0,
/// <summary>
/// 正在操作
/// </summary>
Operating = 1,
/// <summary>
/// 运行中
/// </summary>
Running = 2
}
public sealed class LinkerTunAppNatItemInfo
{
public IPAddress IP { get; set; }
public byte PrefixLength { get; set; }
}
}