// get latest tun/tap device info
        public static void reloadTunTap(TunTap tun)
        {
            string guid = tun.devGuid;
            string name = GetInterfaceName(guid);

            tun.name = name;
        }
        public void open()
        {
            if (validate())
            {
                // tap file
                string fileName = TunTap.USERMODEDEVICEDIR + tun.devGuid + TunTap.TAP_WIN_SUFFIX;
                IntPtr handle   = TunTap.CreateFile(fileName, FileAccess.ReadWrite,
                                                    FileShare.ReadWrite, 0, FileMode.Open, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, IntPtr.Zero);
                tap = new FileStream(new SafeFileHandle(handle, true), FileAccess.ReadWrite, 10000, true);

                int    len;
                IntPtr ps   = Marshal.AllocHGlobal(1);
                var    flag = TunTap.DeviceIoControl(
                    handle,                       // hDevice
                    TunTap.TAP_WIN_IOCTL_GET_MAC, // IO control code
                    ps, 100,                      // IN buffer and size
                    ps, 100,                      // OUT buffer and size
                    out len,                      // size returned
                    IntPtr.Zero                   // overlapped
                    );

                if (!flag)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // set the status of the device to be connected
                IntPtr pstatus = Marshal.AllocHGlobal(4);
                Marshal.WriteInt32(pstatus, 1);
                TunTap.DeviceIoControl(
                    handle,                                // hDevice
                    TunTap.TAP_WIN_IOCTL_SET_MEDIA_STATUS, // IO control code
                    pstatus, 4,                            // IN buffer and size
                    pstatus, 4,                            // OUT buffer and size
                    out len,                               // size returned
                    IntPtr.Zero                            // overlapped
                    );

                // config tun
                IntPtr ptun = Marshal.AllocHGlobal(12);
                Marshal.WriteInt32(ptun, 0, 0x0100030a);
                Marshal.WriteInt32(ptun, 4, 0x0000030a);
                Marshal.WriteInt32(ptun, 8, unchecked ((int)0x00ffffff));
                TunTap.DeviceIoControl(
                    handle,
                    TunTap.TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
                    ptun, 12,
                    ptun, 12,
                    out len,
                    IntPtr.Zero
                    );

                this.isOpen = true;
            }
        }
        public static void FixNetworkInterface(
            TunTap tun,
            string newname      = DEFAULT_INTERFACE_NAME,
            string address      = DEFAULT_INTERFACE_ADDRESS,
            string netmask      = DEFAULT_INTERFACE_MASK,
            string primaryDNS   = DEFAULT_INTERFACE_PRI_DNS,
            string secondaryDNS = DEFAULT_INTERFACE_SEC_DNS
            )
        {
            string guid = tun.devGuid;
            string name = GetInterfaceName(guid);

            if (name != "")
            {
                SetInterfaceStaticAddress(name, address, netmask);
                SetPrimaryDNS(name, primaryDNS);
                SetSecondaryDNS(secondaryDNS);
                SetInterfaceName(name, newname);
                SetGlobalRoute();
                reloadTunTap(tun);
            }
        }
        public TunTapService(String guid)
        {
            TunTap tun = new TunTap(guid);

            this.tun = tun;
        }
 public TunTapService(TunTap tun)
 {
     this.tun = tun;
 }