locked
How to setup a VPN connection in code?

    Question

  • In my C# program, how can I detect if there is a VPN connection to another machine and setup a connection if needed? I have known the IP address of the target machine and the VPN username/password.

    Thanks!
    Monday, July 25, 2005 8:17 AM

Answers

  • There are RAS APIs to do this. 
    Here is some sample code to get started



      public static string GetCurrentConnectoid()
      {
       return GetCurrentConnectoid(null);
      }
      public static string GetCurrentConnectoid(TextWriter Log)
      {
       if(Log != null) Log.WriteLine("\n----> In ConnectoidHelper::GetCurrentConnectoid");
       uint dwSize = (uint) Marshal.SizeOf(typeof(RASCONN));
       if(Log != null) Log.WriteLine("\tUsing struct size dwSize:" + dwSize.ToString());
       uint count = 4;
       uint statusCode = 0;
       RASCONN[] connections = null;
       while (true)
       {
        uint cb = checked(dwSize * count);
        connections = new RASCONN[count];
        connections[0].dwSize = dwSize;
        statusCode = RasEnumConnections(connections, ref cb, ref count);
        if(Log != null) Log.WriteLine("\tRasEnumConnections() returned count:" + count + " statusCode: " + statusCode + " cb:" + cb);
        if (statusCode != ERROR_BUFFER_TOO_SMALL)
        {
         break;
        }
        count = checked(cb + dwSize - 1) / dwSize;
       }
       if (count == 0 || statusCode != 0)
       {
        return null;
       }

       for (uint i=0; i < count; i++)
       {
        if(Log != null)
        {
         Log.WriteLine("\t-------- RASCONN ------------");
         Log.WriteLine("\tRASCONN[" + i + "]");
         Log.WriteLine("\tRASCONN[" + i + "].dwSize: " + connections//emoticons/emotion-55.gif" alt="Idea" />.dwSize);
         Log.WriteLine("\tRASCONN[" + i + "].hrasconn: " + connectionsIdea.hrasconn);
         Log.WriteLine("\tRASCONN[" + i + "].szEntryName: " + connectionsIdea.szEntryName);
         Log.WriteLine("\tRASCONN[" + i + "].szDeviceType: " + connectionsIdea.szDeviceType);
         Log.WriteLine("\tRASCONN[" + i + "].szDeviceName: " + connectionsIdea.szDeviceName);
        }

        RASCONNSTATUS connectionStatus = new RASCONNSTATUS();
        connectionStatus.dwSize = (uint)Marshal.SizeOf(connectionStatus);
        statusCode = RasGetConnectStatus(connectionsIdea.hrasconn, ref connectionStatus);
        if(Log != null) Log.WriteLine("RasGetConnectStatus() returned statusCode: " + statusCode + " dwSize: " + connectionStatus.dwSize);
        if (statusCode==0) {
         if(Log != null)
         {
          Log.WriteLine("\t\t-------- RASCONN Status ------------");
          Log.WriteLine("\t\tRSCONN[" + i + "].RASCONNSTATUS.dwSize: " + connectionStatus.dwSize);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.rasconnstate: " + connectionStatus.rasconnstate);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.dwError: " + connectionStatus.dwError);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.szDeviceType: " + connectionStatus.szDeviceType);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.szDeviceName: " + connectionStatus.szDeviceName);
         }
         if (connectionStatus.rasconnstate==RASCONNSTATE.RASCS_Connected) {
          if(Log != null) Log.WriteLine("r::GetCurrentConnectoid() called RasGetConnectStatus() statusCode: " + statusCode + " dwSize: " + connectionStatus.dwSize);
          return connectionsIdea.szEntryName;
         }
        }
        else
        {
         if(Log != null)
         {
          Log.WriteLine("\t\tRasGetConnectStatus returned a statuscode: " + statusCode + " message " + RasErrors.ErrorMessage(statusCode));
         }

        }
       }

       return null;
      } //End of get current Connectoid


      public struct RASCONN {
       internal uint dwSize;
       internal IntPtr hrasconn;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxEntryName + 1)]
       internal string szEntryName;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceType + 1)]
       internal string szDeviceType;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceName + 1)]
       internal string szDeviceName;
       /* None of these are supported on Windows 98.
       MSDN lies twice: there is no dwSessionId at all, and szPhonebook and dwSubEntry are not on Win98.
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
          internal string szPhonebook;
          internal uint dwSubEntry;
          internal Guid guidEntry;
          internal uint dwFlags;
          internal ulong luid;
       */
      }

      [StructLayout(LayoutKind.Sequential, Pack=4, CharSet=CharSet.Auto)]
      struct RASCONNSTATUS {
       internal uint dwSize;
       internal RASCONNSTATE rasconnstate;
       internal uint dwError;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceType + 1)]
       internal string szDeviceType;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceName + 1)]
       internal string szDeviceName;
       /* Not supported on Windows 98.
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxPhoneNumber + 1)]
          internal string szPhoneNumber;
       */
      }

     

    Monday, July 25, 2005 9:01 PM

All replies

  • There are RAS APIs to do this. 
    Here is some sample code to get started



      public static string GetCurrentConnectoid()
      {
       return GetCurrentConnectoid(null);
      }
      public static string GetCurrentConnectoid(TextWriter Log)
      {
       if(Log != null) Log.WriteLine("\n----> In ConnectoidHelper::GetCurrentConnectoid");
       uint dwSize = (uint) Marshal.SizeOf(typeof(RASCONN));
       if(Log != null) Log.WriteLine("\tUsing struct size dwSize:" + dwSize.ToString());
       uint count = 4;
       uint statusCode = 0;
       RASCONN[] connections = null;
       while (true)
       {
        uint cb = checked(dwSize * count);
        connections = new RASCONN[count];
        connections[0].dwSize = dwSize;
        statusCode = RasEnumConnections(connections, ref cb, ref count);
        if(Log != null) Log.WriteLine("\tRasEnumConnections() returned count:" + count + " statusCode: " + statusCode + " cb:" + cb);
        if (statusCode != ERROR_BUFFER_TOO_SMALL)
        {
         break;
        }
        count = checked(cb + dwSize - 1) / dwSize;
       }
       if (count == 0 || statusCode != 0)
       {
        return null;
       }

       for (uint i=0; i < count; i++)
       {
        if(Log != null)
        {
         Log.WriteLine("\t-------- RASCONN ------------");
         Log.WriteLine("\tRASCONN[" + i + "]");
         Log.WriteLine("\tRASCONN[" + i + "].dwSize: " + connections//emoticons/emotion-55.gif" alt="Idea" />.dwSize);
         Log.WriteLine("\tRASCONN[" + i + "].hrasconn: " + connectionsIdea.hrasconn);
         Log.WriteLine("\tRASCONN[" + i + "].szEntryName: " + connectionsIdea.szEntryName);
         Log.WriteLine("\tRASCONN[" + i + "].szDeviceType: " + connectionsIdea.szDeviceType);
         Log.WriteLine("\tRASCONN[" + i + "].szDeviceName: " + connectionsIdea.szDeviceName);
        }

        RASCONNSTATUS connectionStatus = new RASCONNSTATUS();
        connectionStatus.dwSize = (uint)Marshal.SizeOf(connectionStatus);
        statusCode = RasGetConnectStatus(connectionsIdea.hrasconn, ref connectionStatus);
        if(Log != null) Log.WriteLine("RasGetConnectStatus() returned statusCode: " + statusCode + " dwSize: " + connectionStatus.dwSize);
        if (statusCode==0) {
         if(Log != null)
         {
          Log.WriteLine("\t\t-------- RASCONN Status ------------");
          Log.WriteLine("\t\tRSCONN[" + i + "].RASCONNSTATUS.dwSize: " + connectionStatus.dwSize);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.rasconnstate: " + connectionStatus.rasconnstate);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.dwError: " + connectionStatus.dwError);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.szDeviceType: " + connectionStatus.szDeviceType);
          Log.WriteLine("\t\tRASCONN[" + i + "].RASCONNSTATUS.szDeviceName: " + connectionStatus.szDeviceName);
         }
         if (connectionStatus.rasconnstate==RASCONNSTATE.RASCS_Connected) {
          if(Log != null) Log.WriteLine("r::GetCurrentConnectoid() called RasGetConnectStatus() statusCode: " + statusCode + " dwSize: " + connectionStatus.dwSize);
          return connectionsIdea.szEntryName;
         }
        }
        else
        {
         if(Log != null)
         {
          Log.WriteLine("\t\tRasGetConnectStatus returned a statuscode: " + statusCode + " message " + RasErrors.ErrorMessage(statusCode));
         }

        }
       }

       return null;
      } //End of get current Connectoid


      public struct RASCONN {
       internal uint dwSize;
       internal IntPtr hrasconn;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxEntryName + 1)]
       internal string szEntryName;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceType + 1)]
       internal string szDeviceType;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceName + 1)]
       internal string szDeviceName;
       /* None of these are supported on Windows 98.
       MSDN lies twice: there is no dwSessionId at all, and szPhonebook and dwSubEntry are not on Win98.
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
          internal string szPhonebook;
          internal uint dwSubEntry;
          internal Guid guidEntry;
          internal uint dwFlags;
          internal ulong luid;
       */
      }

      [StructLayout(LayoutKind.Sequential, Pack=4, CharSet=CharSet.Auto)]
      struct RASCONNSTATUS {
       internal uint dwSize;
       internal RASCONNSTATE rasconnstate;
       internal uint dwError;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceType + 1)]
       internal string szDeviceType;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceName + 1)]
       internal string szDeviceName;
       /* Not supported on Windows 98.
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxPhoneNumber + 1)]
          internal string szPhoneNumber;
       */
      }

     

    Monday, July 25, 2005 9:01 PM
  • In the above post all the light bulb icons should actually be Idea.  We are looking into a method to stop this from happening when code snippets are provided. 
    Sunday, August 21, 2005 6:41 AM
  • I'm guessing that the definition for

    RASCONNSTATE

    is missing from the sample code?

    Monday, September 12, 2005 9:25 PM

  •   public enum RASCONNSTATE {
       Unknown = -1,
       RASCS_OpenPort = 0,
       RASCS_PortOpened,
       RASCS_ConnectDevice,
       RASCS_DeviceConnected,
       RASCS_AllDevicesConnected,
       RASCS_Authenticate,
       RASCS_AuthNotify,
       RASCS_AuthRetry,
       RASCS_AuthCallback,
       RASCS_AuthChangePassword,
       RASCS_AuthProject,
       RASCS_AuthLinkSpeed,
       RASCS_AuthAck,
       RASCS_ReAuthenticate,
       RASCS_Authenticated,
       RASCS_PrepareForCallback,
       RASCS_WaitForModemReset,
       RASCS_WaitForCallback,
       RASCS_Projected,
       RASCS_StartAuthentication,    // Windows 95 only
       RASCS_CallbackComplete,       // Windows 95 only
       RASCS_LogonNetwork,           // Windows 95 only
       RASCS_SubEntryConnected,
       RASCS_SubEntryDisconnected,
       RASCS_Interactive = RASCS_PAUSED,
       RASCS_RetryAuthentication,
       RASCS_CallbackSetByCaller,
       RASCS_PasswordExpired,
       RASCS_InvokeEapUI,
       RASCS_Connected = RASCS_DONE,
       RASCS_Disconnected
      }
    Monday, September 12, 2005 9:36 PM
  • how do use your code in C# console based applications or windows based applications?

    how to setup accept incoming connections in C# code?
    I want sample code for vpn connection in C# code?

    Friday, September 16, 2005 6:42 AM
  • This piece of code is really interesting.  But since i am a fresher, i couldnt understand it clear and i am not able to reproduce the same in my code.  Actually whats my requirement is to

    establish a VPN  connection through my application in C# Framework 1.1.  and copy some files from that networks Machine.  I couldnt establish a VPN connection through my application.  Could you pls explain me regarding this issue.

     

    Regards,

    Sathish.N.

    Thursday, September 06, 2007 12:53 PM
  • I have a pocket PC C++ code that uses RAS API and can establish a programmatically configured connection to a VPN.

    My requirement is to rewrite it for C#.

     

    Thank you for the above code since it gave me an idea about applying such an interface. However I could not compile it correctly since there are lots of things that are missing in my code. The errors are on ras enum elements and unmanaged marchaling variables.

     

    Clould you tell me please , in a more beginner's manner, what liberaries I have to add as a reference or how I should configure my .NET project or this class to compile it correctly?

     

    Thank you ,

    A.Oveissian

     

     

    Thursday, February 21, 2008 5:30 PM
  • I am interested to know if there exists any file like rasphone.exe for the Pocket PC that I can call it in my program? I think this will be a shorter way that I can overcome all the RAS API C# programming difficulties.

     

    If anyone knows the answer please tell me how the arguments must be passed throgh this file in the pocket PC.

     

    Thank you,

    A. Oveissian 

    Thursday, February 21, 2008 5:47 PM
  • This may be an old thread, but if you're trying to do anything related to rasapi32.dll or rasdlg.dll from a .NET language, you should check out the DotRas project on CodePlex. It should have what you're looking for.

    http://www.codeplex.com/DotRas
    • Proposed as answer by Jeff Winn Wednesday, March 25, 2009 3:31 PM
    Wednesday, March 25, 2009 3:31 PM
  • hi  A.Oveissian ,I am  intrested your answer , i am looking for code that uses ras api create a vpn connection with c++,can you give me your code ?thanks a lot!

    I want to create a vpn connection with c++ code (vc++), and the functions including  create a  new vpn, edit it (for example i can change its ip address),connect it ,hang up it .can you give me some suggestion?

    Friday, April 30, 2010 8:49 AM
  • Hi.. Jordanhgl, i too do the VPN Connection with C++. If you have finished the creation of new VPN connetion programmatically with c++. Please send me the source code.

    And i have IP address, Username and Password of VPN connection. If you have any idea regarding to this vpn connection with  c++ , please feel free to send me the deatils.

    Thanks in advance

     

    Thursday, May 12, 2011 9:20 AM
  • Hi.. A. Oveissian , i have to do the VPN Connection with C++. Please send me the source code.And i have IP address, Username and Password of VPN connection. If you have any idea regarding to this vpn connection with  c++ , please feel free to send me the deatils. I have tried in many ways and searched in Internet but i did not get any answer regarding this. I need to finish it it's very urgent. Can you please give me suggestion how to make the VPN connection with C++ as soon as possible...

    Thanks in advance...

    Thursday, May 12, 2011 9:24 AM