SHARE
TWEET

GetBestInterface() in C#

a guest Nov 18th, 2011 766 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. public class NetworkInterfaceHelper
  2. {
  3.     private static readonly Dictionary<string, NetworkInterface> m_networkInterfaces;
  4.  
  5.     static NetworkInterfaceHelper()
  6.     {
  7.         m_networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().ToDictionary(o => o.Id);
  8.     }
  9.        
  10.     public static NetworkInterface GetBestInterface(IPAddress address)
  11.     {
  12.         byte[] byteArray1 = address.GetAddressBytes();
  13.  
  14.         uint ipaddr = BitConverter.ToUInt32(byteArray1, 0);
  15.         uint interfaceIndex;
  16.         int error = IPHelperInvoke.GetBestInterface(ipaddr, out interfaceIndex);
  17.  
  18.         if (error != 0)
  19.         {
  20.             throw new InvalidOperationException(string.Format("Error while calling GetBestInterface(). Error={0}", error));
  21.         }
  22.            
  23.         var indexedIpAdapterInfo = AdapterInfo.IndexedIpAdapterInfos[interfaceIndex];
  24.  
  25.         return m_networkInterfaces[indexedIpAdapterInfo.AdapterName];
  26.     }
  27. }
  28.    
  29. public class AdapterInfo
  30. {
  31.     public static IEnumerable<IPHelperInvoke.IP_ADAPTER_INFO> IpAdapterInfos { get; private set; }
  32.     public static Dictionary<uint, IPHelperInvoke.IP_ADAPTER_INFO> IndexedIpAdapterInfos { get; private set; }
  33.        
  34.        
  35.     static AdapterInfo()
  36.     {
  37.         IpAdapterInfos = RetrieveAdapters();
  38.         IndexedIpAdapterInfos = IpAdapterInfos.ToDictionary(o => (uint)o.Index);
  39.     }
  40.  
  41.     private static IEnumerable<IPHelperInvoke.IP_ADAPTER_INFO> RetrieveAdapters()
  42.     {
  43.         long structSize = Marshal.SizeOf(typeof(IPHelperInvoke.IP_ADAPTER_INFO));
  44.         IntPtr pArray = Marshal.AllocHGlobal(new IntPtr(structSize));
  45.  
  46.         int ret = IPHelperInvoke.GetAdaptersInfo(pArray, ref structSize);
  47.            
  48.         IntPtr pEntry = pArray;
  49.         if (ret == IPHelperInvoke.ERROR_BUFFER_OVERFLOW)
  50.         {
  51.             // Buffer was too small, reallocate the correct size for the buffer.
  52.             pArray = Marshal.ReAllocHGlobal(pArray, new IntPtr(structSize));
  53.             ret = IPHelperInvoke.GetAdaptersInfo(pArray, ref structSize);
  54.         }
  55.  
  56.         List<IPHelperInvoke.IP_ADAPTER_INFO> result = new List<IPHelperInvoke.IP_ADAPTER_INFO>();
  57.  
  58.         if (ret == 0)
  59.         {
  60.             do
  61.             {
  62.                 // Retrieve the adapter info from the memory address
  63.                 IPHelperInvoke.IP_ADAPTER_INFO entry = (IPHelperInvoke.IP_ADAPTER_INFO)Marshal.PtrToStructure(pEntry, typeof(IPHelperInvoke.IP_ADAPTER_INFO));
  64.  
  65.                 result.Add(entry);
  66.  
  67.                 // Get next adapter (if any)
  68.                 pEntry = entry.Next;
  69.             }
  70.             while (pEntry != IntPtr.Zero);
  71.  
  72.             Marshal.FreeHGlobal(pArray);
  73.         }
  74.         else
  75.         {
  76.             Marshal.FreeHGlobal(pArray);
  77.         }
  78.  
  79.         return result;
  80.     }
  81. }
  82.  
  83. public class IPHelperInvoke
  84. {
  85.     public const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
  86.  
  87.     public const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
  88.  
  89.     public const int MAX_ADAPTER_NAME_LENGTH = 256;
  90.  
  91.     public const int ERROR_BUFFER_OVERFLOW = 111;
  92.  
  93.     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  94.     public struct IP_ADDRESS_STRING
  95.     {
  96.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
  97.         public string Address;
  98.     }
  99.  
  100.     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  101.     public struct IP_ADDR_STRING
  102.     {
  103.         public IntPtr Next;
  104.         public IP_ADDRESS_STRING IpAddress;
  105.         public IP_ADDRESS_STRING IpMask;
  106.         public Int32 Context;
  107.     }
  108.  
  109.     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  110.     public struct IP_ADAPTER_INFO
  111.     {
  112.         public IntPtr Next;
  113.         public Int32 ComboIndex;
  114.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]
  115.         public string AdapterName;
  116.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
  117.         public string AdapterDescription;
  118.         public UInt32 AddressLength;
  119.         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
  120.         public byte[] Address;
  121.         public Int32 Index;
  122.         public UInt32 Type;
  123.         public UInt32 DhcpEnabled;
  124.         public IntPtr CurrentIpAddress;
  125.         public IP_ADDR_STRING IpAddressList;
  126.         public IP_ADDR_STRING GatewayList;
  127.         public IP_ADDR_STRING DhcpServer;
  128.         public bool HaveWins;
  129.         public IP_ADDR_STRING PrimaryWinsServer;
  130.         public IP_ADDR_STRING SecondaryWinsServer;
  131.         public Int32 LeaseObtained;
  132.         public Int32 LeaseExpires;
  133.     }
  134.  
  135.     [DllImport("iphlpapi.dll", CharSet = CharSet.Ansi)]
  136.     public static extern int GetAdaptersInfo(IntPtr pAdapterInfo, ref Int64 pBufOutLen);
  137.  
  138.     [DllImport("iphlpapi.dll", SetLastError = true)]
  139.     public static extern int GetBestInterface(UInt32 DestAddr, out UInt32 BestIfIndex);
  140. }
  141.  
  142.  
RAW Paste Data
Top