# C#在linux使用tun网卡

你可以可以直接nuget使用 linker.tun

1、P/Invoke 一些api

C#
internal static class LinuxAPI
{

    [DllImport("libc.so.6", EntryPoint = "ioctl", SetLastError = true)]
    internal static extern int Ioctl(SafeHandle device, uint request, byte[] dat);

    internal static int Ioctl(string name, SafeHandle device, uint request)
    {
        byte[] ifreqFREG0 = Encoding.ASCII.GetBytes(name);
        Array.Resize(ref ifreqFREG0, 16);
        byte[] ifreqFREG1 = { 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        byte[] ifreq = BytesPlusBytes(ifreqFREG0, ifreqFREG1);
        return LinuxAPI.Ioctl(device, request, ifreq);
    }
    internal static byte[] BytesPlusBytes(byte[] A, byte[] B)
    {
        byte[] ret = new byte[A.Length + B.Length - 1 + 1];
        int k = 0;
        for (var i = 0; i <= A.Length - 1; i++)
            ret[i] = A[i];
        k = A.Length;
        for (var i = k; i <= ret.Length - 1; i++)
            ret[i] = B[i - k];
        return ret;
    }
}

2、创建tun网卡

C#
//创建
ip tuntap add mode tun dev linker
//设置IP
ip addr add 10.18.18.2/24 dev linker
//启用
ip link set dev linker up
//设置MTU
ip link set dev linker mtu 1400

3、打开网卡

C#
 SafeFileHandle safeFileHandle = File.OpenHandle("/dev/net/tun", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, FileOptions.Asynchronous);
 if (safeFileHandle.IsInvalid)
 {
     safeFileHandle?.Dispose();
     return false;
 }

 int ioctl = LinuxAPI.Ioctl("linker", safeFileHandle, 1074025674);
 if (ioctl != 0)
 {
     safeFileHandle?.Dispose();
     return false;
 }
 
 FileStream fs = new FileStream(safeFileHandle, FileAccess.ReadWrite, 1500);

4、从网卡读取数据

C#
byte[] buffer = new byte[2 * 1024];
int length = fs.Read(buffer.AsSpan());

5、将数据写入网卡

C#
 ReadOnlyMemory<byte> buffer;//你的数据包
 
 fs.Write(buffer.Span);
 fs.Flush();