Monday, May 14, 2007

IP Address information in WinNT family systems

Recently I came across an issue, where I had to dig into the details of how IP address information is stored in Windows. Our CTO asked me whether it is possible to create a simple application/script so that it will be easy for the user to change between different addresses with ease. At that moment, the network administrator was having a tough time, running to every machine, whenever there is a problem.

In the early stages of the research work itself
, I found that the IP address information is stored in the Windows registry. Some information from CodeProject guided me in that direction. The key HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Networkcards in the registry holds all the information about the installed network cards. Different cards will have different subkeys under this key. You can see the Description and ServiceName parameters in this section.

Next phase is finding the actual information, including IP address, subnet mask and default gateway. Besides that, since the plan is to move to another network completely, we need both preferred and alternate DNS addresses. After a little bit of research work, I found the specific key, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces. It does have one or more subkeys (in GUID format) and when you open them, you can find all the required keys, IPAddress, SubnetMask, DefaultGateway and NameServer. IPAddress, SubnetMask and DefaultGateway keys are of type REG_MULTI_SZ and the DNS information is stored in a single REG_SZ value, separated by commas, under the name NameServer.

Now we have the required information. It must be easy to create a simple program for the management of IP information. Win32 API functions RegOpenKeyEx, RegEnumKeyEx, RegQueryValueEx, RegSetValueEx etc. can be used for the manipulation of registry. If you are using a .Net family language, built-in classes are also available. Care should be taken about the fact that REG_MULTI_SZ value ends with two null-characters, instead of one null character.

After changing the values in the registry, I found yet another issue - bit serious one. It is possible to change the text value in the registry, but the system is still holding the previous value. So it was necessary to notify the change. After spending some time digging through all the articles, I found a method. It is by using the DhcpNotifyConfigChange function, which is implemented in the Dhcpcsvc.dll. It is not properly documented in MSDN. We can obtain a pointer to this function using the GetProcAddress function call and then it is possible to send the notification message.

The rest is all imagination. You can do whatever you want to make your application more user-friendly. Creating and managing profiles (storing all the required information in the ini files for easy switching of addresses), listing all the available adapters and addresses in the system etc. are some of them. We dont need any advanced controls for doing this.

Thats all about the background information. Hope that it was useful for you. Happy programming...

Developing a Ping function in Visual C++ and using it in VB .Net / C#

In this article, I will explain how to create a function for checking the connectivity between two machines programatically. It will be implemented as a Visual C++ dll (Win32). Also, I will explain how to create VB .Net and C# wrappers for this dll, so that this dll can be accessed from these languages very easily.

Ping is a program that tests connectivity between two systems running TCP/IP, checking whether or not another host is reachable. The program, originally written by Mike Muuss (http://ftp.arl.mil/~mike/ping.html), uses ICMP echo request/reply messages, but does not use a transport layer (TCP or UDP). Ping also measures the round-trip time to the host.

The Internet Control Message Protocol (ICMP)

The ICMP protocol includes the so-called Echo request and Echo reply messages. A host sends an ICMP echo request message to a specified destination. Any machine that receives an echo request formulates an echo reply and returns it to the original sender. The echo request and associated reply can be used to test whether a destination is reachable and responding. In general you can use this functionality whenever you need some low-level, application-independent reachability info.

Microsoft has their own API for an ICMP.DLL that their ping and tracert applications use (which are both non-GUI text-based console applications). This is a proprietary API, and all function calls that involve network functions operate in blocking mode. They still include it with WinSock 2 implementations, and are documented for the Windows CE platform. For the details about ICMP API, please visit the site www.sockets.com/ms_icmp.htm.

Microsoft used to disclaim this API about as strongly as possible. The README.TXT that once accompanied it said:

[DISCLAIMER]

We have had requests in the past to expose the functions exported from icmp.dll. The files in this directory are provided for your convenience in building applications which make use of ICMPSendEcho(). Notice that the functions in icmp.dll are not considered part of the Win32 API and will not be supported in future releases. Once we have a more complete solution in the operating system, this DLL, and the functions it exports, will be dropped.

Despite this frightening warning, seems Microsoft changed their mind. It doesn't look like the API going away any time soon, as it remains available in new platforms. Fortunately, we have an alternative with raw sockets and setsockopt(IP_TTL) support in WinSock 2 implementations. I will try to create another version of this function, using this alternative.

The Technique

The ICMPSendEcho() function sends an ICMP echo request to the specified destination IP address and returns any replies received within the timeout specified. The API is synchronous, requiring the process to spawn a thread before calling the API to avoid blocking. An open IcmpHandle is required for the request to complete. IcmpCreateFile() and IcmpCloseHandle() functions are used to create and destroy the context handle.