Retrieving Network Information (Windows Embedded CE 6.0)

1/6/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.

#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

Concepts

IP Helper Code Samples