< GetInterfaceInfo, GetIfEntry & GetIfTable Examples | IP Helper Functions Main | GetIpInterfaceTable & IP Statistics Examples >
What do we have in this chapter 13 part 11?
|
Getting an Interface Table Program Example
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 interface table and
// prints the number of entries in the table and some data on each entry
//
//
// Link to ws2_32.lib
#include <winsock2.h>
#include <ws2tcpip.h>
// Link to Iphlpapi.lib
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
// Note: could also use malloc() and free()
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
int main(int argc, char **argv)
{
// Declare and initialize variables
DWORD dwSize = 0;
DWORD dwRetVal = 0;
int i, j;
// variables used for GetIfTable and GetIfEntry
MIB_IFTABLE *pIfTable;
MIB_IFROW *pIfRow;
// Allocate memory for our pointers.
pIfTable = (MIB_IFTABLE *) MALLOC(sizeof (MIB_IFTABLE));
if (pIfTable == NULL)
{
printf("Error allocating memory needed to call GetIfTable()!\n");
return 1;
}
else
printf("Memory allocation for GetIfTable() call is OK!\n");
// Make an initial call to GetIfTable to get the necessary size into dwSize
dwSize = sizeof (MIB_IFTABLE);
if (GetIfTable(pIfTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
{
printf("Not enough buffer! Re-allocating...\n");
FREE(pIfTable);
pIfTable = (MIB_IFTABLE *) MALLOC(dwSize);
if (pIfTable == NULL)
{
printf("Error allocating memory needed to call GetIfTable()!\n");
return 1;
}
else
printf("Memory needed to call GetIfTable() allocated successfully!\n");
}
// Make a second call to GetIfTable to get the actual data we want
if ((dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE)) == NO_ERROR)
{
printf("GetIfTable() should be fine!\n");
printf("\n\tNum Entries: %ld\n\n", pIfTable->dwNumEntries);
for (i = 0; i < (int) pIfTable->dwNumEntries; i++)
{
pIfRow = (MIB_IFROW *) & pIfTable->table[i];
printf("\tIndex[%d]:\t %ld\n", i, pIfRow->dwIndex);
printf("\tInterfaceName[%d]: %S", i, pIfRow->wszName);
printf("\n");
printf("\tDescription[%d]:\t ", i);
for (j = 0; j < (int) pIfRow->dwDescrLen; j++)
printf("%c", pIfRow->bDescr[j]);
printf("\n");
printf("\tType[%d]:\t ", i);
switch (pIfRow->dwType)
{
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 Lookback\n");
break;
case IF_TYPE_ATM:
printf("ATM\n");
break;
case IF_TYPE_IEEE80211:
printf("IEEE 802.11 Wireless\n");
break;
case IF_TYPE_TUNNEL:
printf("Tunnel type encapsulation\n");
break;
case IF_TYPE_IEEE1394:
printf("IEEE 1394 Firewire\n");
break;
default:
printf("Unknown type %ld\n", pIfRow->dwType);
break;
}
printf("\tMtu[%d]:\t\t %ld\n", i, pIfRow->dwMtu);
printf("\tSpeed[%d]:\t %ld\n", i, pIfRow->dwSpeed);
printf("\tPhysical Addr:\t ");
if (pIfRow->dwPhysAddrLen == 0)
printf("\n");
for (j = 0; j < (int) pIfRow->dwPhysAddrLen; j++)
{
if (j == (pIfRow->dwPhysAddrLen - 1))
printf("%.2X\n", (int) pIfRow->bPhysAddr[j]);
else
printf("%.2X-", (int) pIfRow->bPhysAddr[j]);
}
printf("\tAdmin Status[%d]:\t %ld\n", i, pIfRow->dwAdminStatus);
printf("\tOper Status[%d]:\t ", i);
switch (pIfRow->dwOperStatus)
{
case IF_OPER_STATUS_NON_OPERATIONAL:
printf("Non Operational\n");
break;
case IF_OPER_STATUS_UNREACHABLE:
printf("Unreachable\n");
break;
case IF_OPER_STATUS_DISCONNECTED:
printf("Disconnected\n");
break;
case IF_OPER_STATUS_CONNECTING:
printf("Connecting\n");
break;
case IF_OPER_STATUS_CONNECTED:
printf("Connected\n");
break;
case IF_OPER_STATUS_OPERATIONAL:
printf("Operational\n");
break;
default:
printf("Unknown status %ld\n", pIfRow->dwAdminStatus);
break;
}
printf("\n");
}
} else {
printf("GetIfTable failed with error: \n", dwRetVal);
if (pIfTable != NULL)
{
FREE(pIfTable);
pIfTable = NULL;
}
return 1;
// Here you can use FormatMessage to find out why it failed.
}
if (pIfTable != NULL)
{
FREE(pIfTable);
pIfTable = NULL;
}
return 0;
}
Build and run the project.
--------------------------------------------------------------
The SetIpForwardEntry() function modifies an existing route in the local computer's IPv4 routing table. The following example demonstrates how to change the default gateway to NewGateway. Simply calling GetIpForwardTable, changing the gateway and then calling SetIpForwardEntry will not change the route, but rather will just add a new one. If for some reason there are multiple default gateways present, this code will delete them. Note that the new gateway must be viable; otherwise, TCP/IP will ignore the change. Executing this code will change your IP routing tables and will likely cause network activity to fail.
Windows Vista and later: When the DeleteIpForwardEntry function and then SetIpForwardEntry function are called for the same route table entry on Windows Vista and later, ERROR_NOT_FOUND is returned. The proper way to replicate this example on Windows Vista and later is to use the CreateIpForwardEntry function to create the new route table entry and then delete the old route table entry by calling the DeleteIpForwardEntry function. Create a new empty Win32 console mode application and add the project/solution name.
Add the following source code.
// #ifndef WIN32_LEAN_AND_MEAN
// #define WIN32_LEAN_AND_MEAN
// #endif
//
// Link to ws2_32.lib
#include <winsock2.h>
#include <ws2tcpip.h>
// Link to Iphlpapi.lib
#include <iphlpapi.h>
#include <stdio.h>
// Note: could also use malloc() and free()
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
int main(int argc, char **argv)
{
// Declare and initialize variables
// variables used for SetIfForwardEntry
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
PMIB_IPFORWARDROW pRow = NULL;
DWORD dwSize = 0;
BOOL bOrder = FALSE;
DWORD dwStatus = 0;
// this is in host order Ip Address AA.BB.CC.DD is DDCCBBAA
DWORD NewGateway = 0xDDBBCCAA;
DWORD i;
// Find out how big our buffer needs to be.
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
if (dwStatus == ERROR_INSUFFICIENT_BUFFER)
{
printf("Not enough buffer! Re-allocating...\n");
// Allocate the memory for the table
pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc(dwSize);
if (pIpForwardTable == NULL)
{
printf("Unable to allocate memory for the IPFORWARDTALE!\n");
exit(1);
}
else
printf("Memory allocation for IPFORWARDTALE is successful!\n");
// Now get the table.
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
}
else
printf("GetIpForwardTable() should be fine!\n");
if (dwStatus != ERROR_SUCCESS)
{
printf("getIpForwardTable() failed...\n");
if (pIpForwardTable)
free(pIpForwardTable);
exit(1);
}
else
printf("getIpForwardTable() is OK...\n");
// Search for the row in the table we want. The default gateway has a destination
// of 0.0.0.0. Notice that we continue looking through the table, but copy only
// one row. This is so that if there happen to be multiple default gateways, we can
// be sure to delete them all.
for (i = 0; i < pIpForwardTable->dwNumEntries; i++)
{
if (pIpForwardTable->table[i].dwForwardDest == 0)
{
// We have found the default gateway.
if (!pRow)
{
printf("Default gateway found!\n");
// Allocate some memory to store the row in. This is easier than filling
// in the row structure ourselves, and we can be sure to change only the gateway address.
pRow = (PMIB_IPFORWARDROW) malloc(sizeof (MIB_IPFORWARDROW));
if (!pRow)
{
printf("malloc() failed. Out of memory!\n");
exit(1);
}
else
printf("malloc() should be fine!\n");
// Copy the row.
memcpy(pRow, &(pIpForwardTable->table[i]), sizeof (MIB_IPFORWARDROW));
}
// Delete the old default gateway entry.
dwStatus = DeleteIpForwardEntry(&(pIpForwardTable->table[i]));
if (dwStatus != ERROR_SUCCESS)
{
printf("Could not delete old gateway!\n");
exit(1);
}
else
printf("The old gateway was deleted!\n");
}
}
// Set the nexthop field to our new gateway. All the other properties of the route will
// be the same as they were previously.
pRow->dwForwardNextHop = NewGateway;
// Create a new route entry for the default gateway.
dwStatus = SetIpForwardEntry(pRow);
if (dwStatus == NO_ERROR)
printf("Gateway changed successfully!\n");
else if (dwStatus == ERROR_INVALID_PARAMETER)
printf("Invalid parameter!\n");
else
printf("Error: %d\n", dwStatus);
// Free resources.
if (pIpForwardTable)
free(pIpForwardTable);
if (pRow)
free(pRow);
}
Build and run the project.
< GetInterfaceInfo, GetIfEntry & GetIfTable Examples | IP Helper Functions Main | GetIpInterfaceTable & IP Statistics Examples >