< Interface Table & SetIpForwardEntry Examples | IP Helper Functions Main | GetTcpTable Example >
What do we have in this chapter 13 part 12?
|
Program Example Using GetIpInterfaceTable() Function
The GetIpInterfaceTable() function retrieves the IP interface entries on the local computer. Create a new empty Win32 console mode application and add the project/solution name.
Add the following source code. |
// Description:
// The following example retrieves the IP interface table,
// then prints the values of a few members of the IP interface
// entries in the table.
//
// Minimum system supported: Vista & server 2003
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h.>
// Link to ws2_32.lib
#include <winsock2.h>
#include <ws2ipdef.h>
// Link to Iphlpapi.lib
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Declare and initialize variables
int i;
DWORD dwRetVal = 0;
PMIB_IPINTERFACE_TABLE pipTable = NULL;
dwRetVal = GetIpInterfaceTable(AF_UNSPEC, &pipTable);
if (dwRetVal != NO_ERROR)
{
printf("GetIpInterfaceTable() returned error: %ld\n", dwRetVal);
exit(1);
}
else
printf("GetIpInterfaceTable() should be fine!\n");
// Print some variables from the rows in the table
printf("Number of table entries: %d\n\n", pipTable->NumEntries);
for (i = 0; i < (int) pipTable->NumEntries; i++)
{
printf("Address Family[%d]:\t\t", i);
switch (pipTable->Table[i].Family)
{
case AF_INET:
printf("IPv4\n");
break;
case AF_INET6:
printf("IPv6\n");
break;
default:
printf("Other: %d\n", pipTable->Table[i].Family);
break;
}
printf("Interface LUID NetLuidIndex[%d]:\t %lu\n", i, pipTable->Table[i].InterfaceLuid.Info.NetLuidIndex);
printf("Interface LUID IfType[%d]:\t ", i);
switch (pipTable->Table[i].InterfaceLuid.Info.IfType)
{
case IF_TYPE_OTHER:
printf("Other\n");
break;
case IF_TYPE_ETHERNET_CSMACD:
printf("Ethernet\n");
break;
case IF_TYPE_ISO88025_TOKENRING:
printf("Token ring\n");
break;
case IF_TYPE_PPP:
printf("PPP\n");
break;
case IF_TYPE_SOFTWARE_LOOPBACK:
printf("Software loopback\n");
break;
case IF_TYPE_ATM:
printf("ATM\n");
break;
case IF_TYPE_IEEE80211:
printf("802.11 wireless\n");
break;
case IF_TYPE_TUNNEL:
printf("Tunnel encapsulation\n");
break;
case IF_TYPE_IEEE1394:
printf("IEEE 1394 (Firewire)\n");
break;
default:
printf("Unknown: %d\n",
pipTable->Table[i].InterfaceLuid.Info.IfType);
break;
}
printf("Interface Index[%d]:\t\t %lu\n", i, pipTable->Table[i].InterfaceIndex);
printf("Maximum reassembly size[%d]:\t %lu\n", i, pipTable->Table[i].MaxReassemblySize);
printf("Advertising enabled[%d]:\t\t ", i);
if (pipTable->Table[i].AdvertisingEnabled)
printf("Yes\n");
else
printf("No\n");
printf("Forwarding enabled[%d]:\t\t ", i);
if (pipTable->Table[i].ForwardingEnabled)
printf("Yes\n");
else
printf("No\n");
printf("Network layer MTU[%d]:\t\t %lu\n", i, pipTable->Table[i].NlMtu);
printf("Connected[%d]:\t\t\t ", i);
if (pipTable->Table[i].Connected)
printf("Yes\n");
else
printf("No\n");
printf("Supports wakeup patterns[%d]:\t ", i);
if (pipTable->Table[i].SupportsWakeUpPatterns)
printf("Yes\n");
else
printf("No\n");
printf("Supports neighbor discovery[%d]:\t ", i);
if (pipTable->Table[i].SupportsNeighborDiscovery)
printf("Yes\n");
else
printf("No\n");
printf("Supports router discovery[%d]:\t ", i);
if (pipTable->Table[i].SupportsRouterDiscovery)
printf("Yes\n");
else
printf("No\n");
printf("\n");
}
FreeMibTable(pipTable);
pipTable = NULL;
exit(0);
}
Build and run the project.
Well, this program needs to be run on Vista or Server 2003.
Create a new empty Win32 console mode application and add the project/solution name.
Add the following code.
/*---------------------------------------------------------------------------
Copyright (c) 1998 Microsoft Corporation
Module Name: Ipstatexample
File : Ipstatexamplesrc.cpp
Description: This file demonstrates the use of IP Helper APIs
to get IP statistics.
Original author: Frank Li April 21, 1998
---------------------------------------------------------------------------*/
#include "Ipstat.h"
void Usage(char * pszProgramName)
{
printf("Manipulates IP Statistics.\n");
printf("%s -p proto Shows connections for the protocol specified\n", pszProgramName);
printf(" by proto, proto may be tcp or udp.\n");
printf("%s -s [-p proto] Displays per-protocol statistics.\n", pszProgramName);
printf(" By default, statistics are shown for\n");
printf(" IP, ICMP, TCP and UDP; the -p option\n");
printf(" may be used to specify a subset of the default.\n");
printf("Examples:\n");
printf("> IpStat -p tcp\n");
printf("> IpStat -s\n");
if(WSACleanup() == 0)
printf("WSACleanup() is OK!\n");
else
printf("WSACleanup() failed with error code %d\n", WSAGetLastError());
exit(1);
}
void main(int argc, char **argv)
{
WSADATA wsaData;
if ((argc < 2) || (argv[1][0] != '-'))
Usage(argv[0]);
if (strlen(argv[1]) > 2)
Usage(argv[0]);
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
fprintf(stderr,"\n Wrong version\n");
return;
}
else
printf("WSAStartup() is fine!\n");
switch(argv[1][1])
{
case 'p':
// Print connection table
if (argc == 3)
DoGetConnTable(argv[2]);
else
Usage(argv[0]);
break;
case 's':
// show statistics
if (argc == 4 && argv[2][1] == 'p')
{
// Just a validation...
printf("argv[2][1] = %c\n", argv[2][1]);
// Get stat for a specific protocol
DoGetStat(argv[3]);
}
else if (argc == 2)
// Get stat for all protocols
DoGetStat(NULL);
else
Usage(argv[0]);
break;
default:
// help
Usage(argv[0]);
break;
}
WSACleanup();
}
void DoGetConnTable(char* pszProto)
{
DWORD dwStatus;
PMIB_TCPTABLE pTcpTable;
PMIB_UDPTABLE pUdpTable;
if (_strnicmp(pszProto, "tcp", 3) == 0)
{
// Print Tcp Connnection Table
pTcpTable = NULL;
dwStatus = MyGetTcpTable(pTcpTable, TRUE);
if (dwStatus != NO_ERROR)
{
printf("Couldn't get tcp connection table\n");
if (pTcpTable)
free(pTcpTable);
return;
}
else
{
printf("MyGetTcpTable() is OK!\n");
//DumpTcpTable(pTcpTable);
free(pTcpTable);
}
}
else if (_strnicmp(pszProto, "udp", 3) == 0)
{
//Print Udp Table
pUdpTable = NULL;
dwStatus = MyGetUdpTable(pUdpTable, TRUE);
if (dwStatus != NO_ERROR)
{
printf("Couldn't get udp table.\n");
if (pUdpTable)
free(pUdpTable);
return;
}
else
{
printf("MyGetUdpTable() is OK!\n");
// DumpUdpTable(pUdpTable);
free(pUdpTable);
}
}
else
Usage("Ipstatexample");
}
void DoGetStat(char* pszProto)
{
PMIB_IPSTATS pIpStats;
PMIB_ICMP pIcmpStats;
PMIB_TCPSTATS pTcpStats;
PMIB_UDPSTATS pUdpStats;
if (pszProto == NULL)
{
// by default, display all statistics
pIpStats = NULL;
if (MyGetIpStatistics(pIpStats) != NO_ERROR)
printf("Error in getting ip statistics.\n");
else
{
printf("MyGetIpStatistics() is OK!\n");
// PrintIpStats(pIpStats);
}
if (pIpStats)
free(pIpStats);
pIcmpStats = NULL;
if (MyGetIcmpStatistics(pIcmpStats) != NO_ERROR)
printf("Error in getting icmp statistics.\n");
else
{
printf("MyGetIcmpStatistics() is OK!\n");
// PrintIcmpStats(&(pIcmpStats->stats));
}
if (pIcmpStats)
free(pIcmpStats);
pTcpStats = NULL;
if (MyGetTcpStatistics(pTcpStats) != NO_ERROR)
printf("Error in getting tcp statistics.\n");
else
{
printf("MyGetTcpStatistics() is OK!\n");
// PrintTcpStats(pTcpStats);
}
if (pTcpStats)
free(pTcpStats);
pUdpStats = NULL;
if (MyGetUdpStatistics(pUdpStats) != NO_ERROR)
printf("Error in getting udp statistics.\n");
else
{
printf("MyGetUdpStatistics() is OK!\n");
// PrintUdpStats(pUdpStats);
}
if (pUdpStats)
free(pUdpStats);
}
else if (_strnicmp(pszProto, "ip", 2) == 0)
{
pIpStats = NULL;
if (MyGetIpStatistics(pIpStats) != NO_ERROR)
printf("Error in getting ip statistics.\n");
else
{
printf("MyGetIpStatistics() is OK!\n");
PrintIpStats(pIpStats);
}
if (pIpStats)
free(pIpStats);
}
else if (_strnicmp(pszProto, "icmp", 4) == 0)
{
pIcmpStats = NULL;
if (MyGetIcmpStatistics(pIcmpStats) != NO_ERROR)
printf("Error in getting icmp statistics.\n");
else
{
printf("MyGetIcmpStatistics() is fine!\n");
PrintIcmpStats(&(pIcmpStats->stats));
}
if (pIcmpStats)
free(pIcmpStats);
}
else if (_strnicmp(pszProto, "tcp", 3) == 0)
{
pTcpStats = NULL;
if (MyGetTcpStatistics(pTcpStats) != NO_ERROR)
printf("Error in getting tcp statistics.\n");
else
{
printf("MyGetTcpStatistics() is OK!\n");
PrintTcpStats(pTcpStats);
}
if (pTcpStats)
free(pTcpStats);
}
else if (_strnicmp(pszProto, "udp", 3) == 0)
{
pUdpStats = NULL;
if (MyGetUdpStatistics(pUdpStats) != NO_ERROR)
printf("Error in getting udp statistics.\n");
else
{
printf("MyGetUdpStatistics() is OK!\n");
PrintUdpStats(pUdpStats);
}
if (pUdpStats)
free(pUdpStats);
}
else
printf("No available statistics for %s.\n", pszProto);
}
void DumpTcpTable(PMIB_TCPTABLE pTcpTable)
{
char strState[MAX_STRLEN];
struct in_addr inadLocal, inadRemote;
DWORD dwRemotePort = 0;
char szLocalIp[MAX_STRLEN];
char szRemIp[MAX_STRLEN];
UINT i;
if (pTcpTable != NULL)
{
printf("TCP TABLE\n");
printf("%20s %10s %20s %10s %s\n", "Loc Addr", "Loc Port", "Rem Addr", "Rem Port", "State");
for (i = 0; i < pTcpTable->dwNumEntries; ++i)
{
switch (pTcpTable->table[i].dwState)
{
case MIB_TCP_STATE_CLOSED:
strcpy_s(strState, sizeof(strState), "CLOSED");
break;
case MIB_TCP_STATE_TIME_WAIT:
strcpy_s(strState, sizeof(strState), "TIME_WAIT");
break;
case MIB_TCP_STATE_LAST_ACK:
strcpy_s(strState, sizeof(strState), "LAST_ACK");
break;
case MIB_TCP_STATE_CLOSING:
strcpy_s(strState, sizeof(strState), "CLOSING");
break;
case MIB_TCP_STATE_CLOSE_WAIT:
strcpy_s(strState, sizeof(strState), "CLOSE_WAIT");
break;
case MIB_TCP_STATE_FIN_WAIT1:
strcpy_s(strState, sizeof(strState), "FIN_WAIT1");
break;
case MIB_TCP_STATE_ESTAB:
strcpy_s(strState, sizeof(strState), "ESTAB");
break;
case MIB_TCP_STATE_SYN_RCVD:
strcpy_s(strState, sizeof(strState), "SYN_RCVD");
break;
case MIB_TCP_STATE_SYN_SENT:
strcpy_s(strState, sizeof(strState), "SYN_SENT");
break;
case MIB_TCP_STATE_LISTEN:
strcpy_s(strState, sizeof(strState), "LISTEN");
break;
case MIB_TCP_STATE_DELETE_TCB:
strcpy_s(strState, sizeof(strState), "DELETE");
break;
default:
printf("Error: unknown state!\n");
break;
}
inadLocal.s_addr = pTcpTable->table[i].dwLocalAddr;
if (strcmp(strState, "LISTEN") != 0)
{
dwRemotePort = pTcpTable->table[i].dwRemotePort;
}
else
dwRemotePort = 0;
inadRemote.s_addr = pTcpTable->table[i].dwRemoteAddr;
strcpy_s(szLocalIp, sizeof(szLocalIp), inet_ntoa(inadLocal));
strcpy_s(szRemIp, sizeof(szRemIp), inet_ntoa(inadRemote));
printf("%20s %10u %20s %10u %s\n",
szLocalIp, ntohs((unsigned short)(0x0000FFFF & pTcpTable->table[i].dwLocalPort)),
szRemIp, ntohs((unsigned short)(0x0000FFFF & dwRemotePort)),
strState);
}
}
else
printf("pTcpTable == NULL\n");
}
void DumpUdpTable(PMIB_UDPTABLE pUdpTable)
{
UINT i;
struct in_addr inadLocal;
if (pUdpTable != NULL)
{
printf("UDP TABLE\n");
printf("%20s %10s\n", "Loc Addr", "Loc Port");
for (i = 0; i < pUdpTable->dwNumEntries; ++i)
{
inadLocal.s_addr = pUdpTable->table[i].dwLocalAddr;
printf("%20s %10u \n", inet_ntoa(inadLocal), ntohs((unsigned short)(0x0000FFFF & pUdpTable->table[i].dwLocalPort)));
}
}
else
printf("pUdpTable == NULL!\n");
}
//----------------------------------------------------------------------------
// Wrapper to GetTcpTable()
//----------------------------------------------------------------------------
DWORD MyGetTcpTable(PMIB_TCPTABLE pTcpTable, BOOL fOrder)
{
DWORD status = NO_ERROR;
DWORD statusRetry = NO_ERROR;
DWORD dwActualSize = 0;
fOrder = FALSE;
pTcpTable = (PMIB_TCPTABLE) malloc(sizeof (dwActualSize));
// query for buffer size needed
status = GetTcpTable(pTcpTable, &dwActualSize, fOrder);
if (status == NO_ERROR)
{
printf("No error. GetTcpTable() is OK!\n");
return status;
}
else if (status == ERROR_INSUFFICIENT_BUFFER)
{
// need more space
printf("Not enough space, re-allocate...\n");
free(pTcpTable);
pTcpTable = (PMIB_TCPTABLE) malloc(dwActualSize);
if (pTcpTable == NULL)
{
printf("Memory re-allocation failed for GetIpAddrTable()\n");
exit(1);
}
else
printf("Memory re-allocation for GetIpAddrTable() is OK!\n");
assert(pTcpTable);
// Make a second call
statusRetry = GetTcpTable(pTcpTable, &dwActualSize, fOrder);
printf("pTcpTable->dwNumEntries : %d\n", pTcpTable->dwNumEntries);
DumpTcpTable(pTcpTable);
return statusRetry;
}
else
{
return status;
}
}
//----------------------------------------------------------------------------
// Wrapper to GetUdpTable()
//----------------------------------------------------------------------------
DWORD MyGetUdpTable(PMIB_UDPTABLE pUdpTable, BOOL fOrder)
{
DWORD status = NO_ERROR;
DWORD statusRetry = NO_ERROR;
DWORD dwActualSize = 0;
fOrder = FALSE;
// query for buffer size needed
status = GetUdpTable(pUdpTable, &dwActualSize, fOrder);
if (status == NO_ERROR)
{
printf("No error\n");
return status;
}
else if (status == ERROR_INSUFFICIENT_BUFFER)
{
// need more space
pUdpTable = (PMIB_UDPTABLE) malloc(dwActualSize);
assert(pUdpTable);
statusRetry = GetUdpTable(pUdpTable, &dwActualSize, fOrder);
printf("pUdpTable->dwNumEntries : %d\n", pUdpTable->dwNumEntries);
DumpUdpTable(pUdpTable);
return statusRetry;
}
else
{
return status;
}
}
DWORD MyGetIpStatistics(PMIB_IPSTATS pIpStats)
{
pIpStats = (PMIB_IPSTATS)malloc(sizeof(MIB_IPSTATS));
assert(pIpStats != NULL);
PrintIpStats(pIpStats);
return GetIpStatistics(pIpStats);
}
DWORD MyGetIcmpStatistics(PMIB_ICMP pIcmpStats)
{
pIcmpStats = (PMIB_ICMP)malloc(sizeof(MIB_ICMP));
assert(pIcmpStats != NULL);
PrintIcmpStats(&(pIcmpStats->stats));
return GetIcmpStatistics(pIcmpStats);
}
DWORD MyGetTcpStatistics(PMIB_TCPSTATS pTcpStats)
{
pTcpStats = (PMIB_TCPSTATS)malloc(sizeof(MIB_TCPSTATS));
assert(pTcpStats != NULL);
PrintTcpStats(pTcpStats);
return GetTcpStatistics(pTcpStats);
}
DWORD MyGetUdpStatistics(PMIB_UDPSTATS pUdpStats)
{
pUdpStats = (PMIB_UDPSTATS)malloc(sizeof(MIB_UDPSTATS));
assert(pUdpStats != NULL);
PrintUdpStats(pUdpStats);
return GetUdpStatistics(pUdpStats);
}
void PrintIpStats(PMIB_IPSTATS pStats)
{
if (pStats != NULL)
{
printf("\nIP Statistics:\n");
printf("\
dwForwarding = %lu\n\
dwDefaultTTL = %lu\n\
dwInReceives = %lu\n\
dwInHdrErrors = %lu\n\
dwInAddrErrors = %lu\n\
dwForwDatagrams = %lu\n\
dwInUnknownProtos = %lu\n\
dwInDiscards = %lu\n\
dwInDelivers = %lu\n\
dwOutRequests = %lu\n\
dwRoutingDiscards = %lu\n\
dwOutDiscards = %lu\n\
dwOutNoRoutes = %lu\n\
dwReasmTimeout = %lu\n\
dwReasmReqds = %lu\n\
dwReasmOks = %lu\n\
dwReasmFails = %lu\n\
dwFragOks = %lu\n\
dwFragFails = %lu\n\
dwFragCreates = %lu\n\
dwNumIf = %lu\n\
dwNumAddr = %lu\n\
dwNumRoutes = %lu\n",
pStats->dwForwarding,
pStats->dwDefaultTTL,
pStats->dwInReceives,
pStats->dwInHdrErrors,
pStats->dwInAddrErrors,
pStats->dwForwDatagrams,
pStats->dwInUnknownProtos,
pStats->dwInDiscards,
pStats->dwInDelivers,
pStats->dwOutRequests,
pStats->dwRoutingDiscards,
pStats->dwOutDiscards,
pStats->dwOutNoRoutes,
pStats->dwReasmTimeout,
pStats->dwReasmReqds,
pStats->dwReasmOks,
pStats->dwReasmFails,
pStats->dwFragOks,
pStats->dwFragFails,
pStats->dwFragCreates,
pStats->dwNumIf,
pStats->dwNumAddr,
pStats->dwNumRoutes);
}
}
void PrintIcmpStats(MIBICMPINFO *pStats)
{
if (pStats != NULL)
{
printf("\n%20s %10s %10s\n","ICMP Statistics", "IN", "OUT");
printf("%20s %10s %10s\n","---------------", "------", "------");
printf("%20s %10lu %10lu\n", "dwMsgs", pStats->icmpInStats.dwMsgs, pStats->icmpOutStats.dwMsgs);
printf("%20s %10lu %10lu\n", "dwErrors", pStats->icmpInStats.dwErrors, pStats->icmpOutStats.dwErrors);
printf("%20s %10lu %10lu\n", "dwDestUnreachs", pStats->icmpInStats.dwDestUnreachs, pStats->icmpOutStats.dwDestUnreachs);
printf("%20s %10lu %10lu\n", "dwTimeExcds", pStats->icmpInStats.dwTimeExcds, pStats->icmpOutStats.dwTimeExcds);
printf("%20s %10lu %10lu\n", "dwParmProbs", pStats->icmpInStats.dwParmProbs, pStats->icmpOutStats.dwParmProbs);
printf("%20s %10lu %10lu\n", "dwSrcQuenchs", pStats->icmpInStats.dwSrcQuenchs, pStats->icmpOutStats.dwSrcQuenchs);
printf("%20s %10lu %10lu\n", "dwRedirects", pStats->icmpInStats.dwRedirects, pStats->icmpOutStats.dwRedirects);
printf("%20s %10lu %10lu\n", "dwEchos", pStats->icmpInStats.dwEchos, pStats->icmpOutStats.dwEchos);
printf("%20s %10lu %10lu\n", "dwEchoReps", pStats->icmpInStats.dwEchoReps, pStats->icmpOutStats.dwEchoReps);
printf("%20s %10lu %10lu\n", "dwTimestamps", pStats->icmpInStats.dwTimestamps, pStats->icmpOutStats.dwTimestamps);
printf("%20s %10lu %10lu\n", "dwTimestampReps", pStats->icmpInStats.dwTimestampReps, pStats->icmpOutStats.dwTimestampReps);
printf("%20s %10lu %10lu\n", "dwAddrMasks", pStats->icmpInStats.dwAddrMasks, pStats->icmpOutStats.dwAddrMasks);
printf("%20s %10lu %10lu\n", "dwAddrMaskReps", pStats->icmpInStats.dwAddrMaskReps, pStats->icmpOutStats.dwAddrMaskReps);
}
}
void PrintTcpStats(PMIB_TCPSTATS pStats)
{
if (pStats != NULL)
{
printf("\nTCP Statistics\n");
printf("\
dwRtoAlgorithm = %lu\n\
dwRtoMin = %lu\n\
dwRtoMax = %lu\n\
dwMaxConn = %lu\n\
dwActiveOpens = %lu\n\
dwPassiveOpens = %lu\n\
dwAttemptFails = %lu\n\
dwEstabResets = %lu\n\
dwCurrEstab = %lu\n\
dwInSegs = %lu\n\
dwOutSegs = %lu\n\
dwRetransSegs = %lu\n\
dwInErrs = %lu\n\
dwOutRsts = %lu\n\
dwNumConns = %lu\n",
pStats->dwRtoAlgorithm,
pStats->dwRtoMin,
pStats->dwRtoMax,
pStats->dwMaxConn,
pStats->dwActiveOpens,
pStats->dwPassiveOpens,
pStats->dwAttemptFails,
pStats->dwEstabResets,
pStats->dwCurrEstab,
pStats->dwInSegs,
pStats->dwOutSegs,
pStats->dwRetransSegs,
pStats->dwInErrs,
pStats->dwOutRsts,
pStats->dwNumConns);
}
}
void PrintUdpStats(PMIB_UDPSTATS pStats)
{
if (pStats != NULL)
{
printf("\nUDP Statistics\n");
printf("\
dwInDatagrams = %lu\n\
dwNoPorts = %lu\n\
dwInErrors = %lu\n\
dwOutDatagrams = %lu\n\
dwNumAddrs = %lu\n",
pStats->dwInDatagrams,
pStats->dwNoPorts,
pStats->dwInErrors,
pStats->dwOutDatagrams,
pStats->dwNumAddrs);
}
}
< Interface Table & SetIpForwardEntry Examples | IP Helper Functions Main | GetTcpTable Example >