Определение активного сетевого интерфейса

В приложении.NET как определить, какой сетевой интерфейс используется для связи с данным IP-адресом?

Я работаю на рабочих станциях с несколькими сетевыми интерфейсами, IPv4 и v6, и мне нужно получить адрес "правильного" интерфейса, используемого для трафика на данный сервер баз данных.

6 ответов

Решение

Самый простой способ будет:

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

Теперь, если вам нужен объект NetworkInterface, вы делаете что-то вроде:


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


Другой вариант - использовать P/Invoke и вызвать GetBestInterface() для получения индекса интерфейса, а затем снова выполнить цикл по всем сетевым интерфейсам. Как и прежде, вам придется копаться GetIPProperties() чтобы добраться до IPv4InterfaceProperties.Index имущество).

Ни один из них на самом деле не даст оператору информацию, которую он ищет - он хочет знать, какой интерфейс будет использоваться для достижения определенного пункта назначения. Один из способов сделать то, что вы хотите, - это выполнить оболочку для команды route с помощью класса System.Diagnostics.Process, а затем просмотреть результаты на экране. route PRINT (destination IP) даст вам что-то полезное. Возможно, это не самое лучшее решение, но я могу дать вам только одно.

Информация, которую вы ищете, будет в WMI.

Этот пример использования WMI может помочь вам в большей части:

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....
}

Класс Win32_NetworkAdapterConfiguration предоставит вам информацию о конфигурации ваших адаптеров, например, IP-адреса и т. Д.

Вы также можете запросить класс Win32_NetworkAdapter, чтобы выяснить "статический" для каждого адаптера (максимальная скорость, производитель и т. Д.)

Просто чтобы дать полную картину: другой подход будет использовать Socket.IOControl( SIO_ROUTING_INTERFACE_QUERY, ... )

ConferenceXP включает в себя довольно всеобъемлющую функцию, обертывающую это, работает с IPv4/6 и многоадресными адресами: https://github.com/conferencexp/conferencexp/blob/master/MSR.LST.Net.Rtp/NetworkingBasics/utility.cs#L84

По крайней мере, вы можете начать с этого, давая вам все адреса из DNS для локальной машины.

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

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

это старая тема, но сегодня я ищу ее, но, думаю, найду лучший ответ.

      /// <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);
                }
            }
        }
    }
}

Сегодня у меня работает! (когда ifIndex равен -1, интерфейс не найден)

Другие вопросы по тегам