// Need to link with Ws2_32.lib and Iphlpapi.lib #include #include #include #include #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; }