Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

The following code sample demonstrates the use of IP Helper APIs for retrieving network information about the local system, such as:

It also adds a new IP address that maps to an existing adapter on the local system, by calling AddIPAddress.

Copy Code
#include <stdio.h>
#include <windows.h>
#include "iprtrmib.h"
#include "iphlpapi.h"
#include "winsock2.h"

void main() {
 ULONG  ulOutBufLen;
 DWORD  dwRetVal;
 LPVOID   lpMsgBuf;
 
 RETAILMSG(TRUE, (TEXT("------------------------\n")));
 RETAILMSG(TRUE, (TEXT("This is GetNetworkParams\n")));
 RETAILMSG(TRUE, (TEXT("------------------------\n")));

 FIXED_INFO  *pFixedInfo;
 IP_ADDR_STRING *pIPAddr;

 //Call GetNetworkParams to get the length of the buffer
 ulOutBufLen = 0;
 GetNetworkParams( NULL, &ulOutBufLen );

 //Now that we have the necessary size, allocate the memory
 pFixedInfo = (FIXED_INFO *) malloc( ulOutBufLen );

 dwRetVal = GetNetworkParams( pFixedInfo, &ulOutBufLen );
 if (dwRetVal != NO_ERROR ) {
  RETAILMSG(TRUE, (TEXT("Call to GetNetworkParams failed, error
%d.\n"), dwRetVal));
  free(pFixedInfo);
  return;
 }
 
 RETAILMSG(TRUE, (TEXT("\tHost Name: %s\n"), pFixedInfo ->
HostName));
 RETAILMSG(TRUE, (TEXT("\tDomain Name: %s\n"), pFixedInfo ->
DomainName));
 RETAILMSG(TRUE, (TEXT("\tDNS Servers:\n")));
 RETAILMSG(TRUE, (TEXT("\t\t%s\n"), pFixedInfo ->
DnsServerList.IpAddress.String));

 pIPAddr = pFixedInfo -> DnsServerList.Next;
 while ( pIPAddr ) {
   RETAILMSG(TRUE, (TEXT("\t\t%s\n"), pIPAddr ->
IpAddress.String));
   pIPAddr = pIPAddr -> Next;
 }

 if (pFixedInfo -> EnableRouting)
  RETAILMSG(TRUE, (TEXT("\tEnable Routing: Yes\n")));
 else
  RETAILMSG(TRUE, (TEXT("\tEnable Routing: No\n")));

 if (pFixedInfo -> EnableProxy)
  RETAILMSG(TRUE, (TEXT("\tEnable Proxy: Yes\n")));
 else
  RETAILMSG(TRUE, (TEXT("\tEnable Proxy: No\n")));

 if (pFixedInfo -> EnableDns)
  RETAILMSG(TRUE, (TEXT("\tEnable DNS: Yes\n")));
 else
  RETAILMSG(TRUE, (TEXT("\tEnable DNS: No\n")));

 //free the memory we used;
 free(pFixedInfo);
 ulOutBufLen = 0;


 RETAILMSG(TRUE, (TEXT("------------------------\n")));
 RETAILMSG(TRUE, (TEXT("This is GetAdapatersInfo\n")));
 RETAILMSG(TRUE, (TEXT("------------------------\n")));

 IP_ADAPTER_INFO  *pAdapterInfo;
 IP_ADAPTER_INFO  *pAdapter;

 //Call GetAdaptersInfo to get the size of the buffer
 ulOutBufLen = 0;
 GetAdaptersInfo( NULL, &ulOutBufLen) ;

 //Now that we know the necessary buffer size, allocate the memory
 pAdapterInfo = (IP_ADAPTER_INFO *) malloc( ulOutBufLen );

 dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen);
 if (dwRetVal != ERROR_SUCCESS) {
  RETAILMSG(TRUE, (TEXT("Call to GetAdaptersInfo failed, error
%d.\n"), dwRetVal));
  free (pAdapterInfo);
  return;
 }

 //Loop through the adapters and print info on each one.
 pAdapter = pAdapterInfo;
 
 while (pAdapter) {
  RETAILMSG(TRUE, (TEXT("\tAdapter Name: \t%s\n"),
pAdapter->AdapterName));
  RETAILMSG(TRUE, (TEXT("\tAdapter Desc: \t%s\n"),
pAdapter->Description));
  RETAILMSG(TRUE, (TEXT("\tAdapter Addr: \t%ld\n"),
pAdapter->Address));
  RETAILMSG(TRUE, (TEXT("\tIP Address: \t%s\n"),
pAdapter->IpAddressList.IpAddress.String));
  RETAILMSG(TRUE, (TEXT("\tIP Mask: \t%s\n"),
pAdapter->IpAddressList.IpMask.String));

  RETAILMSG(TRUE, (TEXT("\tGateway: \t%s\n"),
pAdapter->GatewayList.IpAddress.String));
  RETAILMSG(TRUE, (TEXT("\t***\n")));
  if (pAdapter->DhcpEnabled) {
   RETAILMSG(TRUE, (TEXT("\tDHCP Enabled: Yes\n")));
   RETAILMSG(TRUE, (TEXT("\t\tDHCP Server: \t%s\n"),
pAdapter->DhcpServer.IpAddress.String));
   RETAILMSG(TRUE, (TEXT("\tLease Obtained: %ld\n"),
pAdapter->LeaseObtained));
  }
  else
   RETAILMSG(TRUE, (TEXT("\tDHCP Enabled: No\n")));
  if (pAdapter->HaveWins) {
   RETAILMSG(TRUE, (TEXT("\tHave Wins: Yes\n")));
   RETAILMSG(TRUE, (TEXT("\t\tPrimary Wins Server: \t%s\n"),
pAdapter->PrimaryWinsServer.IpAddress.String));
   RETAILMSG(TRUE, (TEXT("\t\tSecondary Wins Server: \t%s\n"),
pAdapter->SecondaryWinsServer.IpAddress.String));
  }
  else
   RETAILMSG(TRUE, (TEXT("\tHave Wins: No\n")));
  pAdapter = pAdapter->Next;
 }

 //Free the memory we used.
 if (pAdapterInfo)
  free(pAdapterInfo);

 
 RETAILMSG(TRUE, (TEXT("------------------------\n")));
 RETAILMSG(TRUE, (TEXT("This is GetInterfaceInfo\n")));
 RETAILMSG(TRUE, (TEXT("------------------------\n")));

 IP_INTERFACE_INFO* pInfo;

 //Call GetInterfaceInfo to get the size of the buffer
 ulOutBufLen = 0;
 GetInterfaceInfo(NULL, &ulOutBufLen);

 //Now that we have the necessary size, allocate the memory and
make a real call.
 pInfo = (IP_INTERFACE_INFO *) malloc(ulOutBufLen);
 dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen);

 if ( dwRetVal != NO_ERROR ) {
  RETAILMSG(TRUE, (TEXT("Call to GetInterfaceInfo failed, error
%d.\n"), dwRetVal));
  free ( pInfo );
  return;
 }

 MIB_IFROW *pInterfaceInfo;
 pInterfaceInfo = (MIB_IFROW *) malloc(sizeof( MIB_IFROW ));

 //Loop through each of the interfaces to get information on each
one.
 RETAILMSG(TRUE, (TEXT("Num Adapters: %ld\n"),
pInfo->NumAdapters));
 for (int x = 0; x < pInfo->NumAdapters; x++) {
  RETAILMSG(TRUE, (TEXT("\tAdapter Name: %ws\n"),
pInfo->Adapter[x].Name));
  RETAILMSG(TRUE, (TEXT("\tAdapter Index: %ld\n"),
pInfo->Adapter[x].Index));

  pInterfaceInfo->dwIndex = pInfo->Adapter[x].Index;
  dwRetVal = GetIfEntry(pInterfaceInfo);

  if (dwRetVal != NO_ERROR) {
   RETAILMSG(TRUE, (TEXT("Call to GetIfEntry failed, error %d.\n"),
dwRetVal));
   free (pInterfaceInfo);
   return;
  }
  
  RETAILMSG(TRUE, (TEXT("\tInterface Info:")));
  RETAILMSG(TRUE, (TEXT("\t\tInterface Name: %ws\n"),
pInterfaceInfo->wszName));
  RETAILMSG(TRUE, (TEXT("\t\tLast operational status change:
%d\n"), pInterfaceInfo->dwLastChange));
  RETAILMSG(TRUE, (TEXT("\t\tOctets In:  %d\n"),
pInterfaceInfo->dwInOctets));
 }

 //Free the memory we allocated.
 free(pInfo);
 free(pInterfaceInfo);

 dwRetVal = FormatMessage( 
  FORMAT_MESSAGE_ALLOCATE_BUFFER | 
  FORMAT_MESSAGE_FROM_SYSTEM | 
  FORMAT_MESSAGE_IGNORE_INSERTS,
  NULL,
  dwRetVal,
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  (LPTSTR) &lpMsgBuf,
  0,
  NULL );

 if (!dwRetVal)
  RETAILMSG(TRUE, (TEXT("\tFormatMessage error.")));

 else
  //Free the memory FormatMessage allocated.
  LocalFree( lpMsgBuf );

 /* THIS WORKS BUT IT TAKES A LONG TIME AND INTERRUPTS NET
CONNECTIONS 
 if ((dwRetVal = IpReleaseAddress(&pInfo->Adapter[0])) ==
NO_ERROR) {
  RETAILMSG(TRUE, (TEXT("Ip Release succeeded.\n")));
 }
 if ((dwRetVal = IpRenewAddress(&pInfo->Adapter[0])) ==
NO_ERROR) {
  RETAILMSG(TRUE, (TEXT("Ip Renew succeeded.\n")));
 }
 /**/

 RETAILMSG(TRUE, (TEXT("----------------------\n")));
 RETAILMSG(TRUE, (TEXT("This is GetIpAddrTable\n")));
 RETAILMSG(TRUE, (TEXT("----------------------\n")));
 
 MIB_IPADDRTABLE  *pIPAddrTable;

 //Call to GetIpAddrTable to get the size of the buffer
 ulOutBufLen = 0;
 GetIpAddrTable(NULL, &ulOutBufLen, FALSE);

 //Now that we have the necessary size, allocate the memory and
make a real call.
 pIPAddrTable = (MIB_IPADDRTABLE *) malloc(ulOutBufLen);
 dwRetVal = GetIpAddrTable(pIPAddrTable, &ulOutBufLen, FALSE);

 if ( dwRetVal != NO_ERROR ) {
  RETAILMSG(TRUE, (TEXT("Call to GetIpAddrTable, error %d.\n"),
dwRetVal));
  free ( pIPAddrTable );
  return;
 }

//Print the addresses in the mapping table
 for (int x = 0; x < (int)pIPAddrTable->dwNumEntries; x++) {
  RETAILMSG(TRUE, (TEXT("Address: %ld\n"),
pIPAddrTable->table[x].dwAddr));
  RETAILMSG(TRUE, (TEXT("\tMask:	%ld\n"),
pIPAddrTable->table[x].dwMask));
  RETAILMSG(TRUE, (TEXT("\tIndex:   %ld\n"),
pIPAddrTable->table[x].dwIndex));
  RETAILMSG(TRUE, (TEXT("\tBCast:   %ld\n"),
pIPAddrTable->table[x].dwBCastAddr));
  RETAILMSG(TRUE, (TEXT("\tReasm:   %ld\n"),
pIPAddrTable->table[x].dwReasmSize));
 }

 UINT iaIPAddress;
 UINT imIPMask;

 //Add a new IP address to the table.
 iaIPAddress = inet_addr("192.168.0.27");
 imIPMask = inet_addr("255.255.255.0");

 ULONG NTEContext = 0;
 ULONG NTEInstance = 0;

 dwRetVal = AddIPAddress(
   iaIPAddress, 
   imIPMask, 
   pIPAddrTable->table[0].
   dwIndex, 
   &NTEContext, 
   &NTEInstance);

 if ( dwRetVal != NO_ERROR) {
  RETAILMSG(TRUE, (TEXT("\tError adding IP address.\n")));
 }

 dwRetVal = FormatMessage( 
  FORMAT_MESSAGE_ALLOCATE_BUFFER | 
  FORMAT_MESSAGE_FROM_SYSTEM | 
  FORMAT_MESSAGE_IGNORE_INSERTS,
  NULL,
  dwRetVal,
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  (LPTSTR) &lpMsgBuf,
  0,
  NULL );

 if (!dwRetVal)  {
  RETAILMSG(TRUE, (TEXT("\tFormatMessage error.")));
 }

 else
  //Free the memory FormatMessage allocated.
  LocalFree( lpMsgBuf );

 //Delete an IP Address.
 dwRetVal = DeleteIPAddress(NTEContext);
 
 if (dwRetVal != NO_ERROR) {
  RETAILMSG(TRUE, (TEXT("Call to DeleteIPAddress failed, error
%d.\n"), dwRetVal));
 }

 
 RETAILMSG(TRUE, (TEXT("-------------------------\n")));
 RETAILMSG(TRUE, (TEXT("This is GetIPStatistics()\n")));
 RETAILMSG(TRUE, (TEXT("-------------------------\n")));

 MIB_IPSTATS   *pStats;

 pStats = (MIB_IPSTATS*) malloc(sizeof(MIB_IPSTATS));
 dwRetVal = GetIpStatistics(pStats);
 
 if (dwRetVal != NO_ERROR) {
  RETAILMSG(TRUE, (TEXT("\tError getting stats, error: %d.\n"),
dwRetVal));
  free(pStats);
  return;
 }

 RETAILMSG(TRUE, (TEXT("\tNumber of IP addresses: %ld\n"),
pStats->dwNumAddr));
 RETAILMSG(TRUE, (TEXT("\tNumber of Interfaces: %ld\n"),
pStats->dwNumIf));
 RETAILMSG(TRUE, (TEXT("\tReceives: %ld\n"),
pStats->dwInReceives));
 RETAILMSG(TRUE, (TEXT("\tOut Requests: %ld\n"),
pStats->dwOutRequests));
 RETAILMSG(TRUE, (TEXT("\tRoutes: %ld\n"),
pStats->dwNumRoutes));
 RETAILMSG(TRUE, (TEXT("\tTimeout Time: %ld\n"),
pStats->dwReasmTimeout));
 RETAILMSG(TRUE, (TEXT("\tIn Delivers: %ld\n"),
pStats->dwInDelivers));
 RETAILMSG(TRUE, (TEXT("\tIn Discards: %ld\n"),
pStats->dwInDiscards));
 RETAILMSG(TRUE, (TEXT("\tTotal In: %ld\n"),
pStats->dwInDelivers + pStats->dwInDiscards));
 RETAILMSG(TRUE, (TEXT("\tIn Header Errors: %ld\n"),
pStats->dwInHdrErrors));

 //Free the memory we allocated.
 free(pStats);
 

 RETAILMSG(TRUE, (TEXT("-------------------------\n")));
 RETAILMSG(TRUE, (TEXT("This is GetTCPStatistics()\n")));
 RETAILMSG(TRUE, (TEXT("-------------------------\n")));

 MIB_TCPSTATS  *pTCPStats;

 pTCPStats = (MIB_TCPSTATS*) malloc (sizeof(MIB_TCPSTATS));

 if ((dwRetVal = GetTcpStatistics(pTCPStats)) != NO_ERROR) {
  RETAILMSG(TRUE, (TEXT("Error getting TCP Stats.\n")));
  free(pTCPStats);
  return;
  }
 
 RETAILMSG(TRUE, (TEXT("\tActive Opens: %ld\n"),
pTCPStats->dwActiveOpens));
 RETAILMSG(TRUE, (TEXT("\tPassive Opens: %ld\n"),
pTCPStats->dwPassiveOpens));
 RETAILMSG(TRUE, (TEXT("\tSegments Recv: %ld\n"), 
pTCPStats->dwInSegs));
 RETAILMSG(TRUE, (TEXT("\tSegments Xmit: %ld\n"),
pTCPStats->dwOutSegs));
 RETAILMSG(TRUE, (TEXT("\tTotal # Conxs: %ld\n"),
pTCPStats->dwNumConns));

 //Free the memory we allocated.
 free(pTCPStats);

 return;
}

See Also