Tiberiu Ana
Tiberiu Ana

Reputation: 3663

Identifying active network interface

In a .NET application, how can I identify which network interface is used to communicate to a given IP address?

I am running on workstations with multiple network interfaces, IPv4 and v6, and I need to get the address of the "correct" interface used for traffic to my given database server.

Upvotes: 27

Views: 37519

Answers (6)

antonio
antonio

Reputation: 718

this a old thread but today I'm looking for this, but find a better answer, I think.

/// <summary>
/// Get ifIndex of ip (ip address to connect)
/// </summary>
/// <param name="ip">IP Address that want to connect</param>
/// <param name="description">Lan card description</param>
/// <param name="ifIndex">interface index</param>
/// <param name="ifAddress">IP Address of Lan Interface</param>
private static void CheckInterface(string ip, out string description, out int ifIndex, out IPAddress ifAddress)
{
    description = "";
    ifIndex = -1;
    ifAddress = IPAddress.Any;
    var myIp = IPAddress.Parse(ip);
    if (!NetworkInterface.GetIsNetworkAvailable()) return;
    foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (!adapter.SupportsMulticast) continue;
        if (adapter.OperationalStatus != OperationalStatus.Up) continue;
        var properties = adapter.GetIPProperties();
        if (!properties.MulticastAddresses.Any()) continue;
        var p = properties.GetIPv4Properties();
        if (p == null) continue;
        foreach (var ipInfo in properties.UnicastAddresses)
        {
            if (ipInfo.Address.AddressFamily == AddressFamily.InterNetwork)
            {
                //Console.WriteLine("Address:{0} == {1}", ipInfo.Address, myIp);
                var adpIp = ipInfo.Address.GetAddressBytes();
                var cmpIp = myIp.GetAddressBytes();
                if ((adpIp[0] == cmpIp[0]) && (adpIp[1] == cmpIp[1]) && (adpIp[2] == cmpIp[2]))
                {
                    description = adapter.Description;
                    ifIndex = p.Index;
                    ifAddress = ipInfo.Address;
                    return;
                    //Console.WriteLine("Name {0} ifIndex {1}", adapter.Description, p.Index);
                }
            }
        }
    }
}

Today, works for me! (when ifIndex is -1, not found an interface)

Upvotes: 0

lxa
lxa

Reputation: 3332

Just to give a complete picture: another approach would be to use Socket.IOControl( SIO_ROUTING_INTERFACE_QUERY, ... )

ConferenceXP includes rather comprehensive function wrapping this, works with IPv4/6 and multicast addresses: https://github.com/conferencexp/conferencexp/blob/master/MSR.LST.Net.Rtp/NetworkingBasics/utility.cs#L84

Upvotes: 2

Yariv
Yariv

Reputation: 574

The simplest way would be:

UdpClient u = new UdpClient(remoteAddress, 1);
IPAddress localAddr = ((IPEndPoint)u.Client.LocalEndPoint).Address;

Now, if you want the NetworkInterface object you do something like:


foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
   IPInterfaceProperties ipProps = nic.GetIPProperties();
   // check if localAddr is in ipProps.UnicastAddresses
}


Another option is to use P/Invoke and call GetBestInterface() to get the interface index, then again loop over all the network interfaces. As before, you'll have to dig through GetIPProperties() to get to the IPv4InterfaceProperties.Index property).

Upvotes: 40

Coderer
Coderer

Reputation: 27244

Neither of these will actually give the OP the info he's looking for -- he wants to know which interface will be used to reach a given destination. One way of doing what you want would be to shell out to the route command using System.Diagnostics.Process class, then screen-scrape the output. route PRINT (destination IP) will get you something useable. That's probably not the best solution, but it's the only one I can give you right now.

Upvotes: 6

Oliver Friedrich
Oliver Friedrich

Reputation: 9240

At least you can start with that, giving you all addresses from dns for the local machine.

IPHostEntry hostEntry = Dns.GetHostEntry(Environment.MachineName);

foreach (System.Net.IPAddress address in hostEntry.AddressList)
{
    Console.WriteLine(address);
}

Upvotes: 2

Paul Nearney
Paul Nearney

Reputation: 6955

The info you are after will be in WMI.

This example using WMI may get you most of the way:

using System.Management;
string query = "SELECT * FROM Win32_NetworkAdapterConfiguration";
ManagementObjectSearcher moSearch = new ManagementObjectSearcher(query);
ManagementObjectCollection moCollection = moSearch.Get();// Every record in this collection is a network interface
foreach (ManagementObject mo in moCollection)
{    
    // Do what you need to here....
}

The Win32_NetworkAdapterConfiguration class will give you info about the configuration of your adapters e.g. ip addresses etc.

You can also query the Win32_NetworkAdapter class to find out 'static'about each adapter (max speed, manufacturer etc)

Upvotes: 3

Related Questions