242 lines
9.2 KiB
C++
242 lines
9.2 KiB
C++
// Need to link with Ws2_32.lib and Iphlpapi.lib
|
|
#include <cstdio>
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#include <iphlpapi.h>
|
|
|
|
#pragma warning(disable : 4996)
|
|
|
|
#pragma comment(lib, "iphlpapi.lib")
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
|
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
|
|
|
/* Note: could also use malloc() and free() */
|
|
|
|
int ShowRouteTable() {
|
|
|
|
// Declare and initialize variables.
|
|
|
|
/* variables used for GetIfForwardTable */
|
|
PMIB_IPFORWARDTABLE pIpForwardTable;
|
|
DWORD dwSize = 0;
|
|
DWORD dwRetVal = 0;
|
|
|
|
char szDestIp[128];
|
|
char szMaskIp[128];
|
|
char szGatewayIp[128];
|
|
|
|
struct in_addr IpAddr;
|
|
|
|
int i;
|
|
|
|
pIpForwardTable = (MIB_IPFORWARDTABLE *)MALLOC(sizeof(MIB_IPFORWARDTABLE));
|
|
if (pIpForwardTable == nullptr) {
|
|
printf("Error allocating memory\n");
|
|
return 1;
|
|
}
|
|
|
|
if (GetIpForwardTable(pIpForwardTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
|
|
FREE(pIpForwardTable);
|
|
pIpForwardTable = (MIB_IPFORWARDTABLE *)MALLOC(dwSize);
|
|
if (pIpForwardTable == nullptr) {
|
|
printf("Error allocating memory\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* Note that the IPv4 addresses returned in
|
|
* GetIpForwardTable entries are in network byte order
|
|
*/
|
|
if ((dwRetVal = GetIpForwardTable(pIpForwardTable, &dwSize, 0)) == NO_ERROR) {
|
|
printf("\tNumber of entries: %d\n", (int)pIpForwardTable->dwNumEntries);
|
|
for (i = 0; i < (int)pIpForwardTable->dwNumEntries; i++) {
|
|
/* Convert IPv4 addresses to strings */
|
|
IpAddr.S_un.S_addr = (u_long)pIpForwardTable->table[i].dwForwardDest;
|
|
strcpy_s(szDestIp, sizeof(szDestIp), inet_ntoa(IpAddr));
|
|
IpAddr.S_un.S_addr = (u_long)pIpForwardTable->table[i].dwForwardMask;
|
|
strcpy_s(szMaskIp, sizeof(szMaskIp), inet_ntoa(IpAddr));
|
|
IpAddr.S_un.S_addr = (u_long)pIpForwardTable->table[i].dwForwardNextHop;
|
|
strcpy_s(szGatewayIp, sizeof(szGatewayIp), inet_ntoa(IpAddr));
|
|
|
|
printf("\n\tRoute[%d] Dest IP: %s\n", i, szDestIp);
|
|
printf("\tRoute[%d] Subnet Mask: %s\n", i, szMaskIp);
|
|
printf("\tRoute[%d] Next Hop: %s\n", i, szGatewayIp);
|
|
printf("\tRoute[%d] If Index: %ld\n", i, pIpForwardTable->table[i].dwForwardIfIndex);
|
|
printf("\tRoute[%d] Type: %ld - ", i, pIpForwardTable->table[i].dwForwardType);
|
|
switch (pIpForwardTable->table[i].dwForwardType) {
|
|
case MIB_IPROUTE_TYPE_OTHER:
|
|
printf("other\n");
|
|
break;
|
|
case MIB_IPROUTE_TYPE_INVALID:
|
|
printf("invalid route\n");
|
|
break;
|
|
case MIB_IPROUTE_TYPE_DIRECT:
|
|
printf("local route where next hop is final destination\n");
|
|
break;
|
|
case MIB_IPROUTE_TYPE_INDIRECT:
|
|
printf("remote route where next hop is not final destination\n");
|
|
break;
|
|
default:
|
|
printf("UNKNOWN Type value\n");
|
|
break;
|
|
}
|
|
printf("\tRoute[%d] Proto: %ld - ", i, pIpForwardTable->table[i].dwForwardProto);
|
|
switch (pIpForwardTable->table[i].dwForwardProto) {
|
|
case MIB_IPPROTO_OTHER:
|
|
printf("other\n");
|
|
break;
|
|
case MIB_IPPROTO_LOCAL:
|
|
printf("local interface\n");
|
|
break;
|
|
case MIB_IPPROTO_NETMGMT:
|
|
printf("static route set through network management \n");
|
|
break;
|
|
case MIB_IPPROTO_ICMP:
|
|
printf("result of ICMP redirect\n");
|
|
break;
|
|
case MIB_IPPROTO_EGP:
|
|
printf("Exterior Gateway Protocol (EGP)\n");
|
|
break;
|
|
case MIB_IPPROTO_GGP:
|
|
printf("Gateway-to-Gateway Protocol (GGP)\n");
|
|
break;
|
|
case MIB_IPPROTO_HELLO:
|
|
printf("Hello protocol\n");
|
|
break;
|
|
case MIB_IPPROTO_RIP:
|
|
printf("Routing Information Protocol (RIP)\n");
|
|
break;
|
|
case MIB_IPPROTO_IS_IS:
|
|
printf("Intermediate System-to-Intermediate System (IS-IS) protocol\n");
|
|
break;
|
|
case MIB_IPPROTO_ES_IS:
|
|
printf("End System-to-Intermediate System (ES-IS) protocol\n");
|
|
break;
|
|
case MIB_IPPROTO_CISCO:
|
|
printf("Cisco Interior Gateway Routing Protocol (IGRP)\n");
|
|
break;
|
|
case MIB_IPPROTO_BBN:
|
|
printf("BBN Internet Gateway Protocol (IGP) using SPF\n");
|
|
break;
|
|
case MIB_IPPROTO_OSPF:
|
|
printf("Open Shortest Path First (OSPF) protocol\n");
|
|
break;
|
|
case MIB_IPPROTO_BGP:
|
|
printf("Border Gateway Protocol (BGP)\n");
|
|
break;
|
|
case MIB_IPPROTO_NT_AUTOSTATIC:
|
|
printf("special Windows auto static route\n");
|
|
break;
|
|
case MIB_IPPROTO_NT_STATIC:
|
|
printf("special Windows static route\n");
|
|
break;
|
|
case MIB_IPPROTO_NT_STATIC_NON_DOD:
|
|
printf("special Windows static route not based on Internet standards\n");
|
|
break;
|
|
default:
|
|
printf("UNKNOWN Proto value\n");
|
|
break;
|
|
}
|
|
|
|
printf("\tRoute[%d] Age: %ld\n", i, pIpForwardTable->table[i].dwForwardAge);
|
|
printf("\tRoute[%d] Metric1: %ld\n", i, pIpForwardTable->table[i].dwForwardMetric1);
|
|
}
|
|
FREE(pIpForwardTable);
|
|
return 0;
|
|
} else {
|
|
printf("\tGetIpForwardTable failed.\n");
|
|
FREE(pIpForwardTable);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int SetRouteTable() {
|
|
|
|
// 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;
|
|
DWORD NewGateway = 0xDDBBCCAA; // this is in host order Ip Address AA.BB.CC.DD is DDCCBBAA
|
|
DWORD i;
|
|
|
|
// Find out how big our buffer needs to be.
|
|
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
|
|
if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
|
|
// 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);
|
|
}
|
|
// Now get the table.
|
|
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
|
|
}
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("getIpForwardTable failed.\n");
|
|
if (pIpForwardTable) {
|
|
free(pIpForwardTable);
|
|
}
|
|
exit(1);
|
|
}
|
|
// 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) {
|
|
// 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);
|
|
}
|
|
// 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
return 0;
|
|
} |