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:
- Hostname and domain name by calling GetNetworkParams.
- Network adapter and interface information by calling GetAdaptersInfo and GetInterfaceInfo, respectively.
- Interface to IP address mapping table by calling GetIpAddrTable.
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;
}