JoshuaB

IPIntertop - Win32 `GetAdaptersAddresses()` for C#

Jul 8th, 2013
1,014
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 17.49 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace WifiLinkSpeed
  10. {
  11.     // Originally from http://www.pinvoke.net/default.aspx/iphlpapi/GetAdaptersAddresses.html
  12.     //  - Extra struct properties that we intoduced with Vista were added
  13.     //  - Tad bit of code clean up
  14.     // By Jaxrtech
  15.  
  16.     public class IPIntertop
  17.     {
  18.         public enum FAMILY : uint
  19.         {
  20.             /// <summary>
  21.             /// IPv4
  22.             /// </summary>
  23.             AF_INET = 2,
  24.             /// <summary>
  25.             /// IPv6
  26.             /// </summary>
  27.             AF_INET6 = 23,
  28.             /// <summary>
  29.             /// Unpecified. Includes both IPv4 and IPv4
  30.             /// </summary>
  31.             AF_UNSPEC = 0
  32.         }
  33.         public enum FLAGS : uint
  34.         {
  35.             GAA_FLAG_SKIP_UNICAST = 0x0001,
  36.             GAA_FLAG_SKIP_ANYCAST = 0x0002,
  37.             GAA_FLAG_SKIP_MULTICAST = 0x0004,
  38.             GAA_FLAG_SKIP_DNS_SERVER = 0x0008,
  39.             GAA_FLAG_INCLUDE_PREFIX = 0x0010,
  40.             GAA_FLAG_SKIP_FRIENDLY_NAME = 0x0020
  41.         }
  42.         public enum ERROR : uint
  43.         {
  44.             ERROR_SUCCESS = 0,
  45.             ERROR_NO_DATA = 232,
  46.             ERROR_BUFFER_OVERFLOW = 111,
  47.             ERROR_INVALID_PARAMETER = 87
  48.         }
  49.         public enum IF_OPER_STATUS : uint
  50.         {
  51.             IfOperStatusUp = 1,
  52.             IfOperStatusDown,
  53.             IfOperStatusTesting,
  54.             IfOperStatusUnknown,
  55.             IfOperStatusDormant,
  56.             IfOperStatusNotPresent,
  57.             IfOperStatusLowerLayerDown,
  58.         }
  59.         public enum IF_TYPE : uint
  60.         {
  61.             IF_TYPE_OTHER = 1,   // None of the below
  62.             IF_TYPE_REGULAR_1822 = 2,
  63.             IF_TYPE_HDH_1822 = 3,
  64.             IF_TYPE_DDN_X25 = 4,
  65.             IF_TYPE_RFC877_X25 = 5,
  66.             IF_TYPE_ETHERNET_CSMACD = 6,
  67.             IF_TYPE_IS088023_CSMACD = 7,
  68.             IF_TYPE_ISO88024_TOKENBUS = 8,
  69.             IF_TYPE_ISO88025_TOKENRING = 9,
  70.             IF_TYPE_ISO88026_MAN = 10,
  71.             IF_TYPE_STARLAN = 11,
  72.             IF_TYPE_PROTEON_10MBIT = 12,
  73.             IF_TYPE_PROTEON_80MBIT = 13,
  74.             IF_TYPE_HYPERCHANNEL = 14,
  75.             IF_TYPE_FDDI = 15,
  76.             IF_TYPE_LAP_B = 16,
  77.             IF_TYPE_SDLC = 17,
  78.             IF_TYPE_DS1 = 18,  // DS1-MIB
  79.             IF_TYPE_E1 = 19,  // Obsolete; see DS1-MIB
  80.             IF_TYPE_BASIC_ISDN = 20,
  81.             IF_TYPE_PRIMARY_ISDN = 21,
  82.             IF_TYPE_PROP_POINT2POINT_SERIAL = 22,  // proprietary serial
  83.             IF_TYPE_PPP = 23,
  84.             IF_TYPE_SOFTWARE_LOOPBACK = 24,
  85.             IF_TYPE_EON = 25,  // CLNP over IP
  86.             IF_TYPE_ETHERNET_3MBIT = 26,
  87.             IF_TYPE_NSIP = 27,  // XNS over IP
  88.             IF_TYPE_SLIP = 28,  // Generic Slip
  89.             IF_TYPE_ULTRA = 29,  // ULTRA Technologies
  90.             IF_TYPE_DS3 = 30,  // DS3-MIB
  91.             IF_TYPE_SIP = 31,  // SMDS, coffee
  92.             IF_TYPE_FRAMERELAY = 32,  // DTE only
  93.             IF_TYPE_RS232 = 33,
  94.             IF_TYPE_PARA = 34,  // Parallel port
  95.             IF_TYPE_ARCNET = 35,
  96.             IF_TYPE_ARCNET_PLUS = 36,
  97.             IF_TYPE_ATM = 37,  // ATM cells
  98.             IF_TYPE_MIO_X25 = 38,
  99.             IF_TYPE_SONET = 39,  // SONET or SDH
  100.             IF_TYPE_X25_PLE = 40,
  101.             IF_TYPE_ISO88022_LLC = 41,
  102.             IF_TYPE_LOCALTALK = 42,
  103.             IF_TYPE_SMDS_DXI = 43,
  104.             IF_TYPE_FRAMERELAY_SERVICE = 44,  // FRNETSERV-MIB
  105.             IF_TYPE_V35 = 45,
  106.             IF_TYPE_HSSI = 46,
  107.             IF_TYPE_HIPPI = 47,
  108.             IF_TYPE_MODEM = 48,  // Generic Modem
  109.             IF_TYPE_AAL5 = 49,  // AAL5 over ATM
  110.             IF_TYPE_SONET_PATH = 50,
  111.             IF_TYPE_SONET_VT = 51,
  112.             IF_TYPE_SMDS_ICIP = 52,  // SMDS InterCarrier Interface
  113.             IF_TYPE_PROP_VIRTUAL = 53,  // Proprietary virtual/internal
  114.             IF_TYPE_PROP_MULTIPLEXOR = 54,  // Proprietary multiplexing
  115.             IF_TYPE_IEEE80212 = 55,  // 100BaseVG
  116.             IF_TYPE_FIBRECHANNEL = 56,
  117.             IF_TYPE_HIPPIINTERFACE = 57,
  118.             IF_TYPE_FRAMERELAY_INTERCONNECT = 58,  // Obsolete, use 32 or 44
  119.             IF_TYPE_AFLANE_8023 = 59,  // ATM Emulated LAN for 802.3
  120.             IF_TYPE_AFLANE_8025 = 60,  // ATM Emulated LAN for 802.5
  121.             IF_TYPE_CCTEMUL = 61,  // ATM Emulated circuit
  122.             IF_TYPE_FASTETHER = 62,  // Fast Ethernet (100BaseT)
  123.             IF_TYPE_ISDN = 63,  // ISDN and X.25
  124.             IF_TYPE_V11 = 64,  // CCITT V.11/X.21
  125.             IF_TYPE_V36 = 65,  // CCITT V.36
  126.             IF_TYPE_G703_64K = 66,  // CCITT G703 at 64Kbps
  127.             IF_TYPE_G703_2MB = 67,  // Obsolete; see DS1-MIB
  128.             IF_TYPE_QLLC = 68,  // SNA QLLC
  129.             IF_TYPE_FASTETHER_FX = 69,  // Fast Ethernet (100BaseFX)
  130.             IF_TYPE_CHANNEL = 70,
  131.             IF_TYPE_IEEE80211 = 71,  // Radio spread spectrum
  132.             IF_TYPE_IBM370PARCHAN = 72,  // IBM System 360/370 OEMI Channel
  133.             IF_TYPE_ESCON = 73,  // IBM Enterprise Systems Connection
  134.             IF_TYPE_DLSW = 74,  // Data Link Switching
  135.             IF_TYPE_ISDN_S = 75,  // ISDN S/T interface
  136.             IF_TYPE_ISDN_U = 76,  // ISDN U interface
  137.             IF_TYPE_LAP_D = 77,  // Link Access Protocol D
  138.             IF_TYPE_IPSWITCH = 78,  // IP Switching Objects
  139.             IF_TYPE_RSRB = 79,  // Remote Source Route Bridging
  140.             IF_TYPE_ATM_LOGICAL = 80,  // ATM Logical Port
  141.             IF_TYPE_DS0 = 81,  // Digital Signal Level 0
  142.             IF_TYPE_DS0_BUNDLE = 82,  // Group of ds0s on the same ds1
  143.             IF_TYPE_BSC = 83,  // Bisynchronous Protocol
  144.             IF_TYPE_ASYNC = 84,  // Asynchronous Protocol
  145.             IF_TYPE_CNR = 85,  // Combat Net Radio
  146.             IF_TYPE_ISO88025R_DTR = 86,  // ISO 802.5r DTR
  147.             IF_TYPE_EPLRS = 87,  // Ext Pos Loc Report Sys
  148.             IF_TYPE_ARAP = 88,  // Appletalk Remote Access Protocol
  149.             IF_TYPE_PROP_CNLS = 89,  // Proprietary Connectionless Proto
  150.             IF_TYPE_HOSTPAD = 90,  // CCITT-ITU X.29 PAD Protocol
  151.             IF_TYPE_TERMPAD = 91,  // CCITT-ITU X.3 PAD Facility
  152.             IF_TYPE_FRAMERELAY_MPI = 92,  // Multiproto Interconnect over FR
  153.             IF_TYPE_X213 = 93,  // CCITT-ITU X213
  154.             IF_TYPE_ADSL = 94,  // Asymmetric Digital Subscrbr Loop
  155.             IF_TYPE_RADSL = 95,  // Rate-Adapt Digital Subscrbr Loop
  156.             IF_TYPE_SDSL = 96,  // Symmetric Digital Subscriber Loop
  157.             IF_TYPE_VDSL = 97,  // Very H-Speed Digital Subscrb Loop
  158.             IF_TYPE_ISO88025_CRFPRINT = 98,  // ISO 802.5 CRFP
  159.             IF_TYPE_MYRINET = 99,  // Myricom Myrinet
  160.             IF_TYPE_VOICE_EM = 100,  // Voice recEive and transMit
  161.             IF_TYPE_VOICE_FXO = 101,  // Voice Foreign Exchange Office
  162.             IF_TYPE_VOICE_FXS = 102,  // Voice Foreign Exchange Station
  163.             IF_TYPE_VOICE_ENCAP = 103,  // Voice encapsulation
  164.             IF_TYPE_VOICE_OVERIP = 104,  // Voice over IP encapsulation
  165.             IF_TYPE_ATM_DXI = 105,  // ATM DXI
  166.             IF_TYPE_ATM_FUNI = 106,  // ATM FUNI
  167.             IF_TYPE_ATM_IMA = 107,  // ATM IMA
  168.             IF_TYPE_PPPMULTILINKBUNDLE = 108,  // PPP Multilink Bundle
  169.             IF_TYPE_IPOVER_CDLC = 109,  // IBM ipOverCdlc
  170.             IF_TYPE_IPOVER_CLAW = 110,  // IBM Common Link Access to Workstn
  171.             IF_TYPE_STACKTOSTACK = 111,  // IBM stackToStack
  172.             IF_TYPE_VIRTUALIPADDRESS = 112,  // IBM VIPA
  173.             IF_TYPE_MPC = 113,  // IBM multi-proto channel support
  174.             IF_TYPE_IPOVER_ATM = 114,  // IBM ipOverAtm
  175.             IF_TYPE_ISO88025_FIBER = 115,  // ISO 802.5j Fiber Token Ring
  176.             IF_TYPE_TDLC = 116,  // IBM twinaxial data link control
  177.             IF_TYPE_GIGABITETHERNET = 117,
  178.             IF_TYPE_HDLC = 118,
  179.             IF_TYPE_LAP_F = 119,
  180.             IF_TYPE_V37 = 120,
  181.             IF_TYPE_X25_MLP = 121,  // Multi-Link Protocol
  182.             IF_TYPE_X25_HUNTGROUP = 122,  // X.25 Hunt Group
  183.             IF_TYPE_TRANSPHDLC = 123,
  184.             IF_TYPE_INTERLEAVE = 124,  // Interleave channel
  185.             IF_TYPE_FAST = 125,  // Fast channel
  186.             IF_TYPE_IP = 126,  // IP (for APPN HPR in IP networks)
  187.             IF_TYPE_DOCSCABLE_MACLAYER = 127,  // CATV Mac Layer
  188.             IF_TYPE_DOCSCABLE_DOWNSTREAM = 128,  // CATV Downstream interface
  189.             IF_TYPE_DOCSCABLE_UPSTREAM = 129,  // CATV Upstream interface
  190.             IF_TYPE_A12MPPSWITCH = 130,  // Avalon Parallel Processor
  191.             IF_TYPE_TUNNEL = 131,  // Encapsulation interface
  192.             IF_TYPE_COFFEE = 132,  // Coffee pot
  193.             IF_TYPE_CES = 133,  // Circuit Emulation Service
  194.             IF_TYPE_ATM_SUBINTERFACE = 134,  // ATM Sub Interface
  195.             IF_TYPE_L2_VLAN = 135,  // Layer 2 Virtual LAN using 802.1Q
  196.             IF_TYPE_L3_IPVLAN = 136,  // Layer 3 Virtual LAN using IP
  197.             IF_TYPE_L3_IPXVLAN = 137,  // Layer 3 Virtual LAN using IPX
  198.             IF_TYPE_DIGITALPOWERLINE = 138,  // IP over Power Lines
  199.             IF_TYPE_MEDIAMAILOVERIP = 139,  // Multimedia Mail over IP
  200.             IF_TYPE_DTM = 140,  // Dynamic syncronous Transfer Mode
  201.             IF_TYPE_DCN = 141,  // Data Communications Network
  202.             IF_TYPE_IPFORWARD = 142,  // IP Forwarding Interface
  203.             IF_TYPE_MSDSL = 143,  // Multi-rate Symmetric DSL
  204.             IF_TYPE_IEEE1394 = 144,  // IEEE1394 High Perf Serial Bus
  205.             IF_TYPE_RECEIVE_ONLY = 145 // TV adapter type
  206.         }
  207.         public enum IP_SUFFIX_ORIGIN : uint
  208.         {
  209.             /// IpSuffixOriginOther -> 0
  210.             IpSuffixOriginOther = 0,
  211.             IpSuffixOriginManual,
  212.             IpSuffixOriginWellKnown,
  213.             IpSuffixOriginDhcp,
  214.             IpSuffixOriginLinkLayerAddress,
  215.             IpSuffixOriginRandom,
  216.         }
  217.         public enum IP_PREFIX_ORIGIN : uint
  218.         {
  219.             /// IpPrefixOriginOther -> 0
  220.             IpPrefixOriginOther = 0,
  221.             IpPrefixOriginManual,
  222.             IpPrefixOriginWellKnown,
  223.             IpPrefixOriginDhcp,
  224.             IpPrefixOriginRouterAdvertisement,
  225.         }
  226.         public enum IP_DAD_STATE : uint
  227.         {
  228.             /// IpDadStateInvalid -> 0
  229.             IpDadStateInvalid = 0,
  230.             IpDadStateTentative,
  231.             IpDadStateDuplicate,
  232.             IpDadStateDeprecated,
  233.             IpDadStatePreferred,
  234.         }
  235.  
  236.         public enum NET_IF_CONNECTION_TYPE : uint
  237.         {
  238.             NET_IF_CONNECTION_DEDICATED = 1,
  239.             NET_IF_CONNECTION_PASSIVE = 2,
  240.             NET_IF_CONNECTION_DEMAND = 3,
  241.             NET_IF_CONNECTION_MAXIMUM = 4
  242.         }
  243.  
  244.         public enum TUNNEL_TYPE : uint {
  245.             TUNNEL_TYPE_NONE = 0,
  246.             TUNNEL_TYPE_OTHER = 1,
  247.             TUNNEL_TYPE_DIRECT = 2,
  248.             TUNNEL_TYPE_6TO4 = 11,
  249.             TUNNEL_TYPE_ISATAP = 13,
  250.             TUNNEL_TYPE_TEREDO = 14,
  251.             TUNNEL_TYPE_IPHTTPS = 15
  252.         }
  253.  
  254.         [StructLayout(LayoutKind.Sequential)]
  255.         public struct GUID {
  256.             uint Data1;
  257.             ushort Data2;
  258.             ushort Data3;
  259.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  260.             byte[] Data4;
  261.         }
  262.  
  263.         private const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
  264.         private const int MAX_ADAPTER_NAME_LENGTH = 256;
  265.         private const int MAX_DHCPV6_DUID_LENGTH = 130;
  266.  
  267.         [StructLayout(LayoutKind.Sequential)]
  268.         public struct SOCKADDR
  269.         {
  270.             /// u_short->unsigned short
  271.             public ushort sa_family;
  272.  
  273.             /// char[14]
  274.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
  275.             public byte[] sa_data;
  276.         }
  277.  
  278.         [StructLayout(LayoutKind.Sequential)]
  279.         public struct SOCKET_ADDRESS
  280.         {
  281.             public IntPtr lpSockAddr;
  282.             public int iSockaddrLength;
  283.         }
  284.  
  285.         [StructLayout(LayoutKind.Sequential)]
  286.         public struct IP_ADAPTER_UNICAST_ADDRESS
  287.         {
  288.             public UInt64 Alignment;
  289.             public IntPtr Next;
  290.             public SOCKET_ADDRESS Address;
  291.             public IP_PREFIX_ORIGIN PrefixOrigin;
  292.             public IP_SUFFIX_ORIGIN SuffixOrigin;
  293.             public IP_DAD_STATE DadState;
  294.             public uint ValidLifetime;
  295.             public uint PreferredLifetime;
  296.             public uint LeaseLifetime;
  297.         }
  298.  
  299.         [StructLayout(LayoutKind.Sequential)]
  300.         public struct IP_ADAPTER_ADDRESSES
  301.         {
  302.             public UInt64 Alignment;
  303.             public IntPtr Next;
  304.             public IntPtr AdapterName;
  305.             public IntPtr FirstUnicastAddress;
  306.             public IntPtr FirstAnycastAddress;
  307.             public IntPtr FirstMulticastAddress;
  308.             public IntPtr FirstDnsServerAddress;
  309.             [MarshalAs(UnmanagedType.LPWStr)]
  310.             public string DnsSuffix;
  311.             [System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)]
  312.             public string Description;
  313.             [System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)]
  314.             public string FriendlyName;
  315.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
  316.             public byte[] PhysicalAddress;
  317.             public uint PhysicalAddressLength;
  318.             public uint Flags;
  319.             public uint Mtu;
  320.             public IF_TYPE IfType;
  321.             public IF_OPER_STATUS OperStatus;
  322.             uint Ipv6IfIndex;
  323.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
  324.             public uint[] ZoneIndices;
  325.             public IntPtr FirstPrefix;
  326.  
  327.             // Items added for Vista
  328.             // May need to be removed on Windows versions below Vista to work properly (?)
  329.             public UInt64 TrasmitLinkSpeed;
  330.             public UInt64 ReceiveLinkSpeed;
  331.             public IntPtr FirstWinsServerAddress;
  332.             public IntPtr FirstGatewayAddress;
  333.             public uint Ipv4Metric;
  334.             public uint Ipv6Metric;
  335.             public UInt64 Luid;
  336.             public SOCKET_ADDRESS Dhcpv4Server;
  337.             public uint CompartmentId;
  338.             public GUID NetworkGuid;
  339.             public NET_IF_CONNECTION_TYPE ConnectionType;
  340.             public TUNNEL_TYPE TunnelType;
  341.             public SOCKET_ADDRESS Dhcpv6Server;
  342.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DHCPV6_DUID_LENGTH)]
  343.             public byte[] Dhcpv6ClientDuid;
  344.             public uint Dhcpv6ClientDuidLength;
  345.             public uint Dhcpv6Iaid;
  346.             public uint FirstDnsSuffix;
  347.         }
  348.  
  349.         [DllImport("iphlpapi.dll")]
  350.         private static extern ERROR GetAdaptersAddresses(uint Family, uint Flags, IntPtr Reserved, IntPtr pAdapterAddresses, ref uint pOutBufLen);
  351.  
  352.         public static string MarshalString(IntPtr text)
  353.         {
  354.             // !!!: This should only be used with IP_ADAPTER_ADDRESSES.AdapterName since it can't be marshalled automatically
  355.             byte[] cName = new byte[MAX_ADAPTER_NAME_LENGTH];
  356.             Marshal.Copy(text, cName, 0, MAX_ADAPTER_NAME_LENGTH);
  357.             string name = Encoding.ASCII.GetString(cName, 0, MAX_ADAPTER_NAME_LENGTH);
  358.  
  359.             return name;
  360.         }
  361.  
  362.         public static IList<IP_ADAPTER_ADDRESSES> GetIPAdapters(FAMILY family)
  363.         {
  364.             List<IP_ADAPTER_ADDRESSES> adapters = new List<IP_ADAPTER_ADDRESSES>();
  365.             uint outBufLen = 0;
  366.             ERROR err = GetAdaptersAddresses((uint)family, (uint)0, IntPtr.Zero, IntPtr.Zero, ref outBufLen);
  367.  
  368.             if (ERROR.ERROR_BUFFER_OVERFLOW == err)
  369.             {
  370.                 IntPtr pAdapterAddresses = Marshal.AllocHGlobal((int)outBufLen);
  371.                 try
  372.                 {
  373.                     err = GetAdaptersAddresses((uint)FAMILY.AF_INET, (uint)0, IntPtr.Zero, pAdapterAddresses, ref outBufLen);
  374.                     if (ERROR.ERROR_SUCCESS == err)
  375.                     {
  376.                         IntPtr currPtr = pAdapterAddresses;
  377.                         while (IntPtr.Zero != currPtr)
  378.                         {
  379.                             IP_ADAPTER_ADDRESSES addr = (IP_ADAPTER_ADDRESSES)Marshal.PtrToStructure(currPtr, typeof(IP_ADAPTER_ADDRESSES));
  380.                             adapters.Add(addr);
  381.  
  382.                             currPtr = addr.Next;
  383.                         }
  384.                     }
  385.                 }
  386.                 finally
  387.                 {
  388.                     Marshal.FreeHGlobal(pAdapterAddresses);
  389.                 }
  390.             }
  391.  
  392.             return adapters;
  393.         }
  394.  
  395.         public static IList<IPAddress> GetIPAddresses(FAMILY family)
  396.         {
  397.             List<IPAddress> addresses = new List<IPAddress>();
  398.  
  399.             foreach (IP_ADAPTER_ADDRESSES addr in GetIPAdapters(family)) {
  400.                 if (IntPtr.Zero != addr.FirstUnicastAddress)
  401.                 {
  402.                     IP_ADAPTER_UNICAST_ADDRESS unicastAddr = (IP_ADAPTER_UNICAST_ADDRESS)Marshal.PtrToStructure(addr.FirstUnicastAddress, typeof(IP_ADAPTER_UNICAST_ADDRESS));
  403.                     if (IntPtr.Zero != unicastAddr.Address.lpSockAddr)
  404.                     {
  405.                         SOCKADDR socketAddr = (SOCKADDR)Marshal.PtrToStructure(unicastAddr.Address.lpSockAddr, typeof(SOCKADDR));
  406.                         byte[] saData = socketAddr.sa_data.Skip(2).Take(4).ToArray();
  407.                         IPAddress ipAddr = new IPAddress(saData);
  408.                         addresses.Add(ipAddr);
  409.                     }
  410.                 }
  411.             }
  412.  
  413.             return addresses;
  414.         }
  415.     }
  416. }
Advertisement
Add Comment
Please, Sign In to add comment