views:

818

answers:

3

We're monitoring usage statistics of a network interface using NetworkInterface.GetIPv4Statistics() in .NET 2.0. This isn't reporting correct statistics for connections over which VPN traffic is being tunneled. Instead - in the case of the Cisco VPN client - the usage is just attributed to a new network interface that just looks like an Ethernet connection.

Windows itself (Vista, at least) adds the VPN statistics to the actual physical interface correctly, so viewing the 'Status' dialog for the original connection shows the correct byte counts. However, the results of the call in .NET do not merge the traffic together.

Is there a way to associate the VPN connection back to the network connection over which it's being tunneled? Failing that, does anyone know which API is being used by the status dialog to retrieve correct statistics?

At the moment we're having to manually detect connections that look like they're VPNs and add their usage to whatever other connection is active, and this doesn't seem like a robust solution.

+1  A: 

I'll have to check when I get to work to see what my config looks like.

One thing that Cisco VPN does is, if configured, disabling split tunneling. What that means is that you are prevented from accessing your local subnet on the connection that is connected to VPN.

The way I can see this, is when my ethernet connection is configured with an IP Address, but doesn't have a Default Gateway.

Supposing that you identify the VPN connection, that gateway-less connection would be your other connection.

Also, have you looked into any WMI classes. Cisco VPN may interact with a WMI class perhaps.

Rob Haupt
I can still see the gateway address for the original (PPP) connection, unfortunately.I'll have a trawl through WMI and see if there's any more information in there. Win32_NetworkAdapter and Win32_NetworkAdapterConfiguration don't add anything useful, though.
Thom
+2  A: 
Mick
Most of the stuff in System.Net.NetworkInformation wraps iphlpapi.dll anyway, so I'm not sure this will help. I'll have a look through the MSDN docs you linked to anyway, and see if there are any other avenues of attack.
Thom
Fair enough. In my opinion, I think you will need quite a bit of P/Invoke for this solution, and you may be better off with a native language like C++/Delphi for this. However, I'll leave that to you. Regards.
Mick
A: 

As Rob suggests, the answer lies within WMI. Win32_PerfFormattedData_RemoteAccess_RasPort seems to be exactly what Windows uses itself - the numbers are the same, byte for byte, whether the VPN is up or not.

I tested with:

static class Program
{
    static void Main()
    {
        var query = new WqlEventQuery("__InstanceModificationEvent", TimeSpan.FromSeconds(1),
                                      "TargetInstance ISA 'Win32_PerfFormattedData_RemoteAccess_RasPort' AND TargetInstance.BytesReceived > 0");

        var watcher = new ManagementEventWatcher(query);
        watcher.EventArrived += EventArrived;
        watcher.Start();

        Console.ReadLine();
    }

    static void EventArrived(object sender, EventArrivedEventArgs e)
    {
        var mo = e.NewEvent["TargetInstance"] as ManagementBaseObject;
        Console.WriteLine("{0:#,0}: {1:#,0} bytes sent, {2:#,0} bytes received", mo["Name"], mo["BytesTransmitted"], mo["BytesReceived"]);
    }
}
Thom
This turns out not to be widely supported. We ended up using a third-party RAS library.
Thom