Click here to Skip to main content
15,881,898 members
Articles / Programming Languages / C#

IP Configuration Information using IP Helper APIs

Rate me:
Please Sign up or sign in to vote.
3.56/5 (5 votes)
25 Aug 2007CPOL3 min read 61K   2.3K   23   5
This article shows you how to create an ipconfig like utility that displays detailed network adapter information.
Image 1

Introduction

This article shows you how to create an ipconfig like utility that displays detailed network adapter information. The advantages of coding another version of ipconfig in C# is not only to understand how to write one in C# but also to learn to utilize information exposed from a single function call like GetAdaptersAddresses.

Background

With the popularity of IPV6 slowly increasing and with Microsoft's built in support for IPV6 starting Windows XP SP2, there is a nascent demand for applications to start supporting IPV6. (There is a US government mandate involved too.)

Most of the recommended changes revolve around using IP version agnostic classes like Sytem.Net.IPAddress or Sytem.Net.IPEndPoint and to utilize the same during calls to Socket library functions offered by System.Net.Sockets. But unfortunately not all applications utilize the Socket API. Many applications that deal directly with network infrastructure have to create raw protocol packets and have to send them directly using specialized Win32 driver APIs like WinPcap. While crafting a TCP/IP packet, one of the key information you need is the sending machine's IP and MAC addresses. With the advent of IPV6, a single network adapter can have multiple IP addresses. For example: an adapter can have Unicast addresses (can be link-local or site-local), Multicast addresses, Anycast addresses and on top of the above can have multiple IPV4 addresses! Also your OS might expose multiple tunnel interface adapters by default. So the key problem lies in identifying the correct interface and the correct IP address to use when sending raw packets. Ipxconfig utilizes the GetAdaptersInfo and GetAdaptersAddresses to extract and display detailed information about each available adapter. You can modify the code that enumerates the adapter information to extract specific information that can be utilized in your applications. For example, you can cast an IP address into a System.Net.IPAddress and query the properties of the IP address. Some of this functionality is utilized while displaying the adapter information.

Using the Code

Ipxconfig is a command line utility that displays detailed information on all the network adapters available in your local machine. The reason for the X in ipxconfig is because it is IP version agnostic.

Usage:
ipxconfig [/4] [/6] [/?]
[/4] Calls GetAdaptersInfo and displays IPV4 information for all valid adapters.
[/6] Calls GetAdaptersAddresses and displays both IPV4 and IPV6 information 
	for all valid adapters. 
Note: The number of adapters displayed is always higher because of tunnelling interfaces.
[/?] Displays the help screen

Implementation

The 2 key IP Helper API functions utilized by ipxconfig are GetAdaptersInfo and GetAdaptersAddresses. All the constants, enumerations and structures necessary for making the calls are present in IpHlpConstants.cs, IpHlpEnumerations.cs and IpHlpStructures.cs respectively. The AdapterInfo class calls one of these functions and prints all the necessary information that has been extracted from the IP_ADAPTER_INFO and IP_ADAPTER_ADDRESSES data structures.

C#
/// The GetAdaptersInfo function retrieves adapter information for the local computer.
/// http://msdn2.microsoft.com/en-us/library/aa365917.aspx

/// If the function succeeds, the return value is ERROR_SUCCESS.
/// If the function fails, the return value is one of the following error codes.
///     ERROR_BUFFER_OVERFLOW
///     ERROR_INVALID_DATA
///     ERROR_INVALID_PARAMETER
///     ERROR_NO_DATA
///     ERROR_NOT_SUPPORTED
///     Other
/// </returns />
[DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
private extern static uint GetAdaptersInfo( IntPtr pAdapterInfo, ref int pOutBufLen);

/// The GetAdaptersAddresses function retrieves the addresses 
/// associated with the adapters on the local computer.
/// http://msdn2.microsoft.com/en-us/library/aa365915.aspx

/// If the function succeeds, the return value is ERROR_SUCCESS.
/// If the function fails, the return value is one of the following error codes.
///     ERROR_ADDRESS_NOT_ASSOCIATED
///     ERROR_BUFFER_OVERFLOW
///     ERROR_INVALID_PARAMETER
///     ERROR_NOT_ENOUGH_MEMORY
///     ERROR_NO_DATA
///     Other
/// </returns />
[DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
private static extern uint GetAdaptersAddresses( uint Family, uint flags, 
	IntPtr Reserved, IntPtr PAdaptersAddresses, ref uint pOutBufLen);

The following code segment is a section from the PrintXp2K3AdapterAddressesInfo function that enumerates all the relevant structures exposed by the IP_ADAPTER_ADDRESSES structure.

C#
// -- UNICAST IP ADDRESS INFORMATION -- //
IP_ADAPTER_UNICAST_ADDRESS ipadapterunicastaddr;
IntPtr next = adapterAddressesBuffer.FirstUnicastAddress;

if (next != (IntPtr)0)
{
    do
    {
        ipadapterunicastaddr = (IP_ADAPTER_UNICAST_ADDRESS)Marshal.PtrToStructure
				(next, typeof(IP_ADAPTER_UNICAST_ADDRESS));
        SOCKET_ADDRESS sock_addr;
        sock_addr = (SOCKET_ADDRESS)ipadapterunicastaddr.Address;
        next = ipadapterunicastaddr.Next;

        //A sockaddr struct
        SOCKADDR sockaddr;
        SOCKADDRIPV6 sockaddripv6;
        IPAddress ipaddr = null;

        //Marshal memory pointer into a struct
        sockaddr = (SOCKADDR)Marshal.PtrToStructure(sock_addr.lpSockAddr, 
			typeof(SOCKADDR));

        //Check if the address family is IPV4
        if (sockaddr.sa_family == (Int32)System.Net.Sockets.AddressFamily.InterNetwork)
        {
            ipaddr = new IPAddress(sockaddr.sa_data);
        }
        else if (sockaddr.sa_family == 
		(Int32)System.Net.Sockets.AddressFamily.InterNetworkV6)
        {
            //Marshal memory pointer into a struct
            sockaddripv6 = (SOCKADDRIPV6)Marshal.PtrToStructure
			(sock_addr.lpSockAddr, typeof(SOCKADDRIPV6));
            ipaddr = new IPAddress(sockaddripv6.sa_data);
        }

        if (ipaddr == null) throw new MemberAccessException
			("Could not parse the interface's IP Address.");

        Trace.WriteLine("\n\tIP Address              :  " + ipaddr.ToString());
        Trace.WriteLine("\t  Address Family        :  " + 
				ipaddr.AddressFamily.ToString());

        if (ipaddr.AddressFamily == AddressFamily.InterNetworkV6)
        {
            Trace.WriteLine("\t  Interface Zone ID     :  %" + 
			adapterAddressesBuffer.ZoneIndices[(uint)
			SCOPE_LEVEL.ScopeLevelInterface].ToString());
            Trace.WriteLine("\t  Is Linklocal Address  :  " + 
			ipaddr.IsIPv6LinkLocal.ToString());
            Trace.WriteLine("\t  Is Multicast Address  :  " + 
			ipaddr.IsIPv6Multicast.ToString());
            Trace.WriteLine("\t  Is Sitelocal Address  :  " + 
			ipaddr.IsIPv6SiteLocal.ToString());
            Trace.WriteLine("\t  Scope ID              :  " + 
			ipaddr.ScopeId.ToString());
        }

    } while (next != (IntPtr)0);
}

Conclusion

I hope this article helps you in your IPV6 development efforts. Feel free to send comments or questions based on this article.

References

History

  • Version 1.0: Supports IP_ADAPTER_ADDRESSES structure available in Microsoft Windows XP and Microsoft Windows 2003 SDK. It is backward compatible with Microsoft Vista.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Application Security Inc.
United States United States
Arunkumar Viswanathan is currently a software engineer at Application Security Inc. in New York City. His interests include electronics (especially audio), photography and anything that is interesting.

Comments and Discussions

 
QuestionDhcpv6ClientDuid member Pin
syka_xxl31-Jul-11 23:16
syka_xxl31-Jul-11 23:16 
GeneralMemory leak in GetAdaptersAddresses function Pin
PadaKwaak4-May-10 10:23
PadaKwaak4-May-10 10:23 
GeneralRe: Memory leak in GetAdaptersAddresses function Pin
Arunkumar Viswanathan5-May-10 11:54
Arunkumar Viswanathan5-May-10 11:54 
QuestionDid you check the System.Net.NetworkInformation namespace? Pin
dchrno26-Aug-07 22:45
dchrno26-Aug-07 22:45 
AnswerRe: Did you check the System.Net.NetworkInformation namespace? Pin
Arunkumar Viswanathan27-Aug-07 5:37
Arunkumar Viswanathan27-Aug-07 5:37 
You are correct. Thanks a lot for the link. This is the fun of contributing to an open source forum. There is always someone one step ahead. Smile | :) But the fact is, most of the API support starts from .Net 2.0. So for applications still using older framework versions, my article will help them.
Thanks.




General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.