1. Introduction
This article is intended to be an introduction to the IP helper API and to the Winsock API. The demo project is named IPConfigEx because it implements the basic functionalities of the "ipconfig" [^] command and some of the "arp" [^]) commands with the ability to send the information displayed as an email.
2. Motivation for the article and for the project
I needed a tool that is able to send an email with the network settings of a Windows box (Win2K, WinXP), and that application had to work without any complicated install procedures or dependencies. I took a look at the WinPCap [^], but that was an overkill for my needs and it requires WinPCap to be installed. The IP Helper API [^] was the solution.
3. How to use the IPConfigEx utility
Since this is a command line tool, the user controls its behavior through command line switches. Without any arguments, the tool will display the list of network adapters followed by the list of the ARP entries.
The commonly used command line switches:
[-i:ip] - shows information about the network adapters
[-i:arp] - show the ARP table
I implemented the email sending function to be driven by default parameters, only the destination email must be specified.
4. Discussion of the IP Helper API methods
The backbone of the project is constructed around the GetAdaptersInfo
and GetIpNetTable
methods. As the MSDN states:
The GetAdaptersInfo
function retrieves adapter information for the local computer. The GetIpNetTable
function retrieves the IP-to-physical address mapping table.
I won't detail here the workings of these methods; anyone interested should look in the source code provided. It's pretty simple.
5. Enumerating the network adapters
To GetAdaptersInfo
call returns a linked list of the adapter info structures. Straightforward.
void AdapterInfo::EnumAdapters()
{
IP_ADAPTER_INFO* pAdapterList = NULL;
IP_ADAPTER_INFO* pAdapter = NULL;
ULONG ulBufLen = 0;
DWORD err = ERROR_SUCCESS;
adapters.clear();
err = ::GetAdaptersInfo(pAdapterList, &ulBufLen);
if (err == ERROR_BUFFER_OVERFLOW)
{
pAdapterList = (IP_ADAPTER_INFO*) ::HeapAlloc(::GetProcessHeap(),
HEAP_ZERO_MEMORY, ulBufLen);
err = ::GetAdaptersInfo(pAdapterList, &ulBufLen);
}
else if (err != ERROR_SUCCESS)
{
fprintf(stderr, "EnumAdapters error. Code: %d\n", err);
return;
}
if (pAdapterList == NULL)
{
fprintf(stderr, "Can't allocate memory on heap "
"(%d bytes): EnumAdapters\n", ulBufLen);
return;
}
pAdapter = pAdapterList;
while (pAdapter != NULL)
{
AdapterEntry adapterEntry;
adapterEntry.index = pAdapter->Index;
adapterEntry.name = pAdapter->AdapterName;
adapterEntry.description = pAdapter->Description;
adapterEntry.mac = IpHelper::HrMacAddress(pAdapter->Address,
pAdapter->AddressLength);
adapterEntry.ip = pAdapter->IpAddressList.IpAddress;
adapterEntry.subnet = pAdapter->IpAddressList.IpMask;
if (strlen(pAdapter->GatewayList.IpAddress.String) > 0)
adapterEntry.gateway = pAdapter->GatewayList.IpAddress;
else
ZeroMemory(&adapterEntry.gateway, 16);
adapterEntry.dhcpEnabled = pAdapter->DhcpEnabled ? true : false;
if (adapterEntry.dhcpEnabled)
adapterEntry.dhcpServer = pAdapter->DhcpServer.IpAddress;
this->EnumDnsServers(adapterEntry);
if (adapters.find(adapterEntry.index) == adapters.end())
adapters[adapterEntry.index] = adapterEntry;
pAdapter = pAdapter->Next;
}
::HeapFree(::GetProcessHeap(), 0, pAdapterList);
}
Again from MSDN:
"The order in which adapters appear in the list returned by this function can be controlled from the Network Connections folder: select the Advanced Settings menu item from the Advanced menu."
I tried and changed the order of the network adapters, but the index of the adapters didn't change.
6. Things to keep in mind
The first version was built using Visual Studio 2005. However, the built executable requires the Visual C++ 2005 redistributable package to be installed. The same project built with Visual Studio 2003 runs just fine on all Win2K and WinXP systems. I wasn't aware of this until this point.
The SMTP message class uses Winsock methods to send the email. So, for that, you need to add ws2_32.lib to your project (Linker -> Input -> Additional dependencies). For the IP Helper API, you need to add iphlpapi.lib as a dependency.
7. To do
- Add the possibility to display the host name of the machine.
- Check for a way to know if there is no link on an interface (media disconnected).
- More detailed command line switches.
8. References
- The "New ipconfig" and the IP Helper API [^]
- About IP Helper [^]
- Windows Networking Overview [^]