LoginSignup
5
6

More than 5 years have passed since last update.

C#でVPN接続(L2TP over IPsec 事前共有キーあり)する

Last updated at Posted at 2017-03-31

需要があるかわからないですが、C#でVPN接続する忘備録。
時間が経っているのでうろ覚え。。。

C#って、こういう処理はすっごい簡単にできそうなんだけど
このVPNに関して言えば、それっぽいWIN APIとかもなくて
とにかく困りました。

softether でVPNサーバーをたててWINアプリからそこにVPN接続したいと考えたんだけど
これがなかなかうまくいかない。
接続方式とか指定しなければもっと簡単に接続できるはずだが、
L2TP over IPsecの事前共有キーありの接続をするのが結構難しかった。

参照でDotRasが必要だった気がする。
結構調べたが情報が古いものが多く、かなり調べると中華系のコミュニティで情報を発見。
で、色んな情報を組み合わせて試行錯誤したけどVISTAぐらいの時代に書かれたソースなので
Win8、Win10で動かないっぽかった。
そっからアレコレ更に試行錯誤してコード調整した記憶がある。

下記はソース(クラス)。クッソ長い。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;


/// <summary>
/// 
/// </summary>
namespace VPNClient
{
    /// <summary>
    /// 
    /// </summary>
    class VPNAPI
    {
        /// <summary>
        /// 
        /// </summary>
        public static int CURRENT_VPN_CONN  = 0;

        /// <summary>
        /// 
        /// </summary>
        public enum RASCredMask
        {
            RASCM_UserName = 0x1,
            RASCM_password = 0x2,
            RASCM_Domain = 0x4,
            RASCM_DefaultCreds = 0x8,
            RASCM_PreSharedKey = 0x10,
            RASCM_ServerPreSharedKey = 0x20,
            RASCM_DDMPreSharedKey = 0x40
        }

        /// <summary>
        /// 
        /// </summary>
        public enum RasEntryOptions
        {
            RASEO_UseCountrAndAreaCodes = 0x00000001,
            RASEO_SpecificIpAddr = 0x00000002,
            RASEO_SpecificNameServers = 0x00000004,
            RASEO_IpHeaderCompression = 0x00000008,
            RASEO_RemoteDefaultGateway = 0x00000010,
            RASEO_DisableLcpExtensions = 0x00000020,
            RASEO_TerminalBeforeDial = 0x00000040,
            RASEO_TerminalAfterDial = 0x00000080,
            RASEO_ModemLights = 0x00000100,
            RASEO_SwCompression = 0x00000200,
            RASEO_RequireEncrptedPw = 0x00000400,
            RASEO_RequireMsEncrptedPw = 0x00000800,
            RASEO_RequireDataEncrption = 0x00001000,
            RASEO_NetworkLogon = 0x00002000,
            RASEO_UseLogonCredentials = 0x00004000,
            RASEO_PromoteAlternates = 0x00008000,
            RASEO_SecureLocalFiles = 0x00010000,
            RASEO_RequireEAP = 0x00020000,
            RASEO_RequirePAP = 0x00040000,
            RASEO_RequireSPAP = 0x00080000,
            RASEO_Custom = 0x00100000,
            RASEO_PreviewPhoneNumber = 0x00200000,
            RASEO_SharedPhoneNumbers = 0x00800000,
            RASEO_PreviewUserPw = 0x01000000,
            RASEO_PreviewDomain = 0x02000000,
            RASEO_ShowDialingProgress = 0x04000000,
            RASEO_RequireCHAP = 0x08000000,
            RASEO_RequireMsCHAP = 0x10000000,
            RASEO_RequireMsCHAP2 = 0x20000000,
            RASEO_RequireW95MSCHAP = 0x40000000

        }

        /// <summary>
        /// 
        /// </summary>
        public enum RasEntryOptions2
        {
            RASEO2_SecureFileAndPrint = 0x1,
            RASEO2_SecureClientForMSNet = 0x2,
            RASEO2_DontNegotiateMultilink = 0x4,
            RASEO2_DontUseRasCredentials = 0x8,
            RASEO2_UsePreSharedKey = 0x10,
            RASEO2_Internet = 0x20,
            RASEO2_DisableNbtOverIP = 0x40,
            RASEO2_UseGlobalDeviceSettings = 0x80,
            RASEO2_ReconnectIfDropped = 0x100,
            RASEO2_SharePhoneNumbers = 0x200,
            //winver > 0x600
            RASEO2_SecureRoutingCompartment = 0x400,
            RASEO2_UseTypicalSettings = 0x800,
            RASEO2_IPv6SpecificNameServer = 0x1000,
            RASEO2_IPv6RemoteDefaultGateway = 0x2000,
            RASEO2_RegisterIpWithDNS = 0x4000,
            RASEO2_UseDNSSuffixForRegistration = 0x8000,
            RASEO2_IPv4ExplicitMetric = 0x10000,
            RASEO2_IPv6ExplicitMetric = 0x20000,
            RASEO2_DisableIKENameEkuCheck = 0x40000,
            //winver > 0x601
            RASEO2_DisableClassBasedStaticRoute = 0x00080000,
            RASEO2_SpecificIPv6Addr = 0x00100000,
            RASEO2_DisableMobility = 0x00200000,
            RASEO2_RequireMachineCertificates = 0x00400000,
            //winver > 0x602
            RASEO2_UsePreSharedKeyForIkev2Initiator = 0x00800000,
            RASEO2_UsePreSharedKeyForIkev2Responder = 0x01000000,
            RASEO2_CacheCredentials = 0x02000000,
            //winver > 0x603
            RASEO2_AutoTriggerCapable = 0x04000000,
            RASEO2_IsThirdPartyProfile = 0x08000000,
            RASEO2_AuthTypeIsOtp = 0x10000000,
            //winver > 0x604
            RASEO2_IsAlwaysOn = 0x20000000,
            RASEO2_IsPrivateNetwork = 0x40000000
        }

        /// <summary>
        /// 
        /// </summary>
        public enum RASNP
        {
            RASNP_NetBEUI = 0x1,
            RASNP_Ipx = 0x2,
            RASNP_Ip = 0x4,
            RASNP_Ipv6 = 0x8
        }


        /// <summary>
        /// 
        /// </summary>
        private const long ET_None = 0;               //   No   encryption

        /// <summary>
        /// 
        /// </summary>
        private const long ET_Require = 1;            //   Require   Encryption

        /// <summary>
        /// 
        /// </summary>
        private const long ET_RequireMax = 2;         //   Require   max   encryption

        /// <summary>
        /// 
        /// </summary>
        private const long ET_Optional = 3;           //   Do   encryption   if   possible.   None   Ok.

        /// <summary>
        /// 
        /// </summary>
        private const long VS_Default = 0;            //   default   (PPTP   for   now)

        /// <summary>
        /// 
        /// </summary>
        private const long VS_PptpOnly = 1;           //   Only   PPTP   is   attempted.

        /// <summary>
        /// 
        /// </summary>
        private const long VS_PptpFirst = 2;          //   PPTP   is   tried   first.

        /// <summary>
        /// 
        /// </summary>
        private const long VS_L2tpOnly = 3;           //  Only   L2TP   is   attempted.

        /// <summary>
        /// 
        /// </summary>
        private const long VS_L2tpFirst = 4;          //   L2TP   is   tried   first.

        /// <summary>
        /// 
        /// </summary>
        private const long RASET_Phone = 1;           //   Phone   lines:   modem,   ISDN,   X.25,   etc

        /// <summary>
        /// 
        /// </summary>
        private const long RASET_Vpn = 2;             //   Virtual   private   network

        /// <summary>
        /// 
        /// </summary>
        private const long RASET_Direct = 3;          //   Direct   connect:   serial,   parallel

        /// <summary>
        /// 
        /// </summary>
        private const long RASET_Internet = 4;        //   BaseCamp   internet

        /// <summary>
        /// 
        /// </summary>
        private const long RASET_Broadband = 5;       //   Broadband

        /// <summary>
        /// 
        /// </summary>
        private const int MAX_PATH = 260;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxAreaCode = 10;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxPhoneNumber = 128;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxDeviceType = 16;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxDeviceName = 128;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxPadType = 32;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxX25Address = 200;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxFacilities = 200;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxUserData = 200;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxDnsSuffix = 256;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxEntryName = 256;

        /// <summary>
        /// 
        /// </summary>
        private const int RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;

        /// <summary>
        /// 
        /// </summary>
        private const int UNLEN = 256;

        /// <summary>
        /// 
        /// </summary>
        private const int PWLEN = 256;

        /// <summary>
        /// 
        /// </summary>
        private const int DNLEN = 16;

        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct GUID
        {
            uint data1;
            UInt16 data2;
            UInt16 data3;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            byte[] data4;
        }

        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct RASIPADDR
        {
            byte a;
            byte b;
            byte c;
            byte d;
        }

        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct RASIPV6ADDR
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            byte[] a;
        }

        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct RASENTRY
        {
            /// <summary>
            /// 
            /// </summary>
            public uint dwSize;

            /// <summary>
            /// 
            /// </summary>
            public uint dwfOptions;

            //
            // Location/phone number.
            //
            public uint dwCountryID;

            /// <summary>
            /// 
            /// </summary>
            public uint dwCountryCode;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxAreaCode + 1))]
            public string szAreaCode;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxPhoneNumber + 1))]
            public string szLocalPhoneNumber;

            /// <summary>
            /// 
            /// </summary>
            public uint dwAlternateOffset;

            //
            // PPP/Ip
            //
            public RASIPADDR ipaddr;

            /// <summary>
            /// 
            /// </summary>
            public RASIPADDR ipaddrDns;

            /// <summary>
            /// 
            /// </summary>
            public RASIPADDR ipaddrDnsAlt;

            /// <summary>
            /// 
            /// </summary>
            public RASIPADDR ipaddrWins;

            /// <summary>
            /// 
            /// </summary>
            public RASIPADDR ipaddrWinsAlt;

            //
            // Framing
            //
            public uint dwFrameSize;

            /// <summary>
            /// 
            /// </summary>
            public uint dwfNetProtocols;

            /// <summary>
            /// 
            /// </summary>
            public uint dwFramingProtocol;

            //
            // Scripting
            //
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAX_PATH)]
            public string szScript;

            //
            // AutoDial
            //
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAX_PATH)]
            public string szAutodialDll;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAX_PATH)]
            public string szAutodialFunc;

            //
            // Device
            //
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxDeviceType + 1))]
            public string szDeviceType;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxDeviceName + 1))]
            public string szDeviceName;

            //
            // X.25
            //
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxPadType + 1))]
            public string szX25PadType;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxX25Address + 1))]
            public string szX25Address;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxFacilities + 1))]
            public string szX25Facilities;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxUserData + 1))]
            public string szX25UserData;

            /// <summary>
            /// 
            /// </summary>
            public uint dwChannels;

            //
            // Reserved
            //
            public uint dwReserved1;

            /// <summary>
            /// 
            /// </summary>
            public uint dwReserved2;

            /// <summary>
            /// 
            /// </summary>
            public uint dwSubEntries;

            /// <summary>
            /// 
            /// </summary>
            public uint dwDialMode;

            /// <summary>
            /// 
            /// </summary>
            public uint dwDialExtraPercent;

            /// <summary>
            /// 
            /// </summary>
            public uint dwDialExtraSampleSeconds;

            /// <summary>
            /// 
            /// </summary>
            public uint dwHangUpExtraPercent;

            /// <summary>
            /// 
            /// </summary>
            public uint dwHangUpExtraSampleSeconds;

            /// <summary>
            /// 
            /// </summary>
            public uint dwIdleDisconnectSeconds;

            /// <summary>
            /// 
            /// </summary>
            public uint dwType;

            /// <summary>
            /// 
            /// </summary>
            public uint dwEncryptionType;

            /// <summary>
            /// 
            /// </summary>
            public uint dwCustomAuthKey;

            /// <summary>
            /// 
            /// </summary>
            public GUID guid;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAX_PATH)] //259
            public string szCustomDialDll;

            /// <summary>
            /// 
            /// </summary>
            public uint dwVpnStrategy;

            /// <summary>
            /// 
            /// </summary>
            public uint dwfOptions2;

            /// <summary>
            /// 
            /// </summary>
            public uint dwfOptions3;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RAS_MaxDnsSuffix)] //255
            public string szDnsSuffix;

            /// <summary>
            /// 
            /// </summary>
            public uint dwTcpWindowSize;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)MAX_PATH)]   //259
            public string szPrerequisitePbk;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)(RAS_MaxEntryName + 1))] //RAS_MaxEntryName=256
            public string szPrerequisiteEntry;

            /// <summary>
            /// 
            /// </summary>
            public uint dwRedialCount;

            /// <summary>
            /// 
            /// </summary>
            public uint dwRedialPause;

            /// <summary>
            /// 
            /// </summary>
            public RASIPV6ADDR ipv6addrDns;

            /// <summary>
            /// 
            /// </summary>
            public RASIPV6ADDR ipv6addrDnsAlt;

            /// <summary>
            /// 
            /// </summary>
            public uint dwIPv4InterfaceMetric;

            /// <summary>
            /// 
            /// </summary>
            public uint dwIPv6InterfaceMetric;

            /// <summary>
            /// 
            /// </summary>
            public RASIPV6ADDR ipv6addr;

            /// <summary>
            /// 
            /// </summary>
            public uint dwIPv6PrefixLength;

            /// <summary>
            /// 
            /// </summary>
            public uint dwNetworkOutageTime;
        }

        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        public struct RASDIALPARAMS
        {
            /// <summary>
            /// 
            /// </summary>
            public int dwSize;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
            public string szEntryName;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxPhoneNumber + 1)]
            public string szPhoneNumber;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxCallbackNumber + 1)]
            public string szCallbackNumber;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = UNLEN + 1)]
            public string szUserName;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PWLEN + 1)]
            public string szPassword;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DNLEN + 1)]
            public string szDomain;

            /// <summary>
            /// 
            /// </summary>
            public int dwSubEntry;

            /// <summary>
            /// 
            /// </summary>
            public int dwCallbackId;
        }

        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct RASCREDENTIALS
        {
            /// <summary>
            /// 
            /// </summary>
            public int dwSize;

            /// <summary>
            /// 
            /// </summary>
            public int dwMask;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)UNLEN + 1)]
            public string szUserName;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)PWLEN + 1)]
            public string szPassword;

            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)DNLEN + 1)]
            public string szDomain;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="unMsg"></param>
        /// <param name="rasconnstate"></param>
        /// <param name="dwError"></param>
        public delegate void Callback(uint unMsg, int rasconnstate, int dwError);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="lpRasDialExtensions"></param>
        /// <param name="lpszPhonebook"></param>
        /// <param name="lprasdialparams"></param>
        /// <param name="dwNotifierType"></param>
        /// <param name="lpvNotifier"></param>
        /// <param name="lphRasConn"></param>
        /// <returns></returns>
        [DllImport("rasapi32.dll ", CharSet = CharSet.Auto)]
        public static extern int RasDial(IntPtr lpRasDialExtensions, string lpszPhonebook, ref RASDIALPARAMS lprasdialparams, int dwNotifierType, Callback lpvNotifier, ref int lphRasConn);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hrasconn"></param>
        /// <returns></returns>
        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
        public extern static int RasHangUp(int hrasconn); // handle to the RAS connection to hang up );

        /// <summary>
        /// 
        /// </summary>
        /// <param name="lpszPhonebook"></param>
        /// <param name="lpszEntry"></param>
        /// <param name="lpRasEntry"></param>
        /// <param name="dwEntryInfoSize"></param>
        /// <param name="lpbDeviceInfo"></param>
        /// <param name="dwDeviceInfoSize"></param>
        /// <returns></returns>
        [DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int RasSetEntryProperties(string lpszPhonebook, string lpszEntry, ref RASENTRY lpRasEntry, uint dwEntryInfoSize, IntPtr lpbDeviceInfo, int dwDeviceInfoSize);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="lpszPhonebook"></param>
        /// <param name="lpszEntry"></param>
        /// <param name="lpCredentials"></param>
        /// <param name="fClearCredentials"></param>
        /// <returns></returns>
        [DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int RasSetCredentials(string lpszPhonebook, string lpszEntry, ref RASCREDENTIALS lpCredentials, int fClearCredentials);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serverIP"></param>
        /// <param name="entryName"></param>
        /// <param name="user"></param>
        /// <param name="pw"></param>
        /// <param name="PreSharedKey"></param>
        /// <returns></returns>
        public static bool rasConnectVPN(string serverIP, string entryName, string user, string pw, string PreSharedKey)
        {
            bool result = false;
            try
            {
                RASENTRY rasEntry = new RASENTRY();
                RASDIALPARAMS RasDialParams = new RASDIALPARAMS();
                RASCREDENTIALS Rascredentials = new RASCREDENTIALS();
                //  uint dwSize = (uint)Marshal.SizeOf(rasEntry);
                uint dwSize = (uint)Marshal.SizeOf(typeof(RASENTRY));

                // System.Runtime.InteropServices.Marshal.SizeOf(typeof(RasDialParams));
                //byte[] lpb = new byte[436];
                //int lpbSize = lpb.Length;
                int ret = -1;
                rasEntry.dwSize = dwSize;
                rasEntry.dwCountryCode = 0;
                rasEntry.dwCountryID = 0;
                rasEntry.dwDialExtraPercent = 75;
                rasEntry.dwDialExtraSampleSeconds = 120;
                rasEntry.dwDialMode = 0;
                rasEntry.dwEncryptionType = (uint)ET_Optional;
                rasEntry.dwfNetProtocols = (uint)(RASNP.RASNP_Ip | RASNP.RASNP_Ipv6);
                rasEntry.dwfOptions = (uint)(RasEntryOptions.RASEO_RemoteDefaultGateway
                | RasEntryOptions.RASEO_SecureLocalFiles
                | RasEntryOptions.RASEO_RequireSPAP
                | RasEntryOptions.RASEO_PreviewUserPw
                | RasEntryOptions.RASEO_PreviewDomain
                //| RasEntryOptions.RASEO_RequireCHAP 
                //| RasEntryOptions.RASEO_RequireMsCHAP 
                | RasEntryOptions.RASEO_RequireMsCHAP2
                | RasEntryOptions.RASEO_ShowDialingProgress
                );
                //rasEntry.dwfOptions2 = 367;
                rasEntry.dwFramingProtocol = 1;
                rasEntry.dwHangUpExtraPercent = 10;
                rasEntry.dwHangUpExtraSampleSeconds = 120;
                rasEntry.dwRedialCount = 3;
                rasEntry.dwRedialPause = 60;
                rasEntry.dwType = (uint)RASET_Vpn;
                rasEntry.dwVpnStrategy = (uint)VS_L2tpOnly;
                rasEntry.szDeviceName = "WAN Miniport (L2TP)";
                rasEntry.szDeviceType = "Vpn";
                rasEntry.szLocalPhoneNumber = serverIP;

                rasEntry.dwfOptions2 = (uint)(RasEntryOptions2.RASEO2_SecureFileAndPrint
                        | RasEntryOptions2.RASEO2_SecureClientForMSNet
                        | RasEntryOptions2.RASEO2_DontNegotiateMultilink
                        //| RasEntryOptions2.RASEO2_DontUseRasCredentials
                        | RasEntryOptions2.RASEO2_Internet
                        | RasEntryOptions2.RASEO2_ReconnectIfDropped
                        | RasEntryOptions2.RASEO2_CacheCredentials
                        );

                if (PreSharedKey != string.Empty)
                {
                    rasEntry.dwfOptions2 += (uint)RasEntryOptions2.RASEO2_UsePreSharedKey;
                }

                ret = RasSetEntryProperties(null, entryName, ref rasEntry, rasEntry.dwSize, IntPtr.Zero, 0);
                if (ret != 0)
                {
                    throw new Exception("FailedToRasSetEntryProperties");
                }

                if (!string.IsNullOrEmpty(PreSharedKey))
                {
                    Rascredentials.dwSize = Marshal.SizeOf(Rascredentials);
                    Rascredentials.dwMask = (int)RASCredMask.RASCM_PreSharedKey;
                    Rascredentials.szPassword = PreSharedKey;
                    ret = RasSetCredentials(null, entryName, ref Rascredentials, 0);
                    if (ret >= 1)
                    {
                        throw new Exception("FailedToRasSetCredentials");
                    }
                }

                RasDialParams.dwSize = Marshal.SizeOf(RasDialParams);
                RasDialParams.szEntryName = entryName;
                RasDialParams.szUserName = user;
                RasDialParams.szPassword = pw;
                int nn = 0;
                ret = RasDial(IntPtr.Zero, null, ref RasDialParams, -1, null, ref nn);

                if (ret >= 1)
                {
                    if (nn > 0)
                        RasHangUp(nn);

                    throw new Exception("FailedToRasDial");
                }

                CURRENT_VPN_CONN = nn;

                result = true;
            }
            catch (Exception ex)
            {
                result = false;
            }
            finally
            {

            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entryName"></param>
        /// <returns></returns>
        public static bool rasDisConnectVPN(string entryName)
        {
            bool result = false;
            if (string.IsNullOrEmpty(entryName))
            {
                return result;
            }

            try
            {
                if (CURRENT_VPN_CONN > 0)
                {
                    RasHangUp(CURRENT_VPN_CONN );
                }
                else
                {
                    //System.Diagnostics.Process.Start("rasdial.exe", entryName + " /d");
                    Process process = new Process();
                    process.StartInfo.FileName = "rasdial.exe ";
                    process.StartInfo.Verb = entryName + " /d runas";
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.CreateNoWindow = true;//not show cmd window
                    process.Start();
                }

                result = true;
            }
            catch (Exception ex)
            {
                result = false;
            }
            finally
            {

            }

            return result;
        }
    }
}

呼び出すときは

if (!VPNAPI.rasConnectVPN('VPNのホスト', '接続名', 'VPNユーザー', 'パスフレーズ', '事前共有キー'))
{
        //"接続ができませんでした";
        return;
}

で、アプリ終了タイミングなど適切なタイミングでVPNを切断する場合は下記のようにする。

VPNAPI.rasDisConnectVPN('接続名');

正直よくわからん。

5
6
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6