SetIpForwardEntry (Compact 2013)

3/26/2014

This function modifies an existing route in the local device's IP routing table. It can also add a new route to the routing table.

Syntax

DWORD SetIpForwardEntry(
  PMIB_IPFORWARDROW pRoute 
);

Parameters

  • pRoute
    [in] Pointer to a MIB_IPFORWARDROW structure that contains the new information for the existing route. The caller must specify values for the dwForwardIfIndex, dwForwardDest, dwForwardMask, dwForwardNextHop, dwForwardPolicy, and dwForwardProto members of the structure. For more information, see Remarks.

Return Value

Return code

Description

NO_ERROR

The function succeeds.

ERROR_ACCESS_DENIED

Access is denied.

ERROR_INVALID_PARAMETER

The pRoute parameter is NULL, or SetIpForwardEntry is unable to read from the memory pointed to by pRoute, or one of the members of the MIB_IPFORWARDROW structure is invalid.

ERROR_NOT_FOUND

The element is not found.

ERROR_NOT_SUPPORTED

The IPv4 transport is not configured on the local device.

Other

Use FormatMessage to obtain the message string for the returned error.

Remarks

The dwForwardProto member of MIB_IPFORWARDROW structure pointed to by the route parameter must be set to MIB_IPPROTO_NETMGMT otherwise SetIpForwardEntry will fail. Routing protocol identifiers are used to identify route information for the specified routing protocol. For example, MIB_IPPROTO_NETMGMT is used to identify route information for IP routing set through network management such as the Dynamic Host Configuration Protocol (DCHP), the Simple Network Management Protocol (SNMP), or by calls to the CreateIpForwardEntry, DeleteIpForwardEntry, or SetIpForwardEntry functions.

The dwForwardAge member the MIB_IPFORWARDROW structure pointed to by the route parameter is currently not used by SetIpForwardEntry. The dwForwardAge member is used only if the Routing and Remote Access Service (RRAS)is running, and then only for routes of type MIB_IPPROTO_NETMGMT as defined on the Protocol Identifiers reference page. When dwForwardAge is set to INFINITE, the route will not be removed based on a time-out value. Any other value for dwForwardAge specifies the number of seconds until the TCP/IP stack will remove the route from the network routing table. A route modified by SetIpForwardEntry will automatically have a default value for dwForwardAge of INFINITE.

Several members of the MIB_IPFORWARDROW structure pointed to by the route parameter are currently not used by SetIpForwardEntry. These members include dwForwardPolicy, dwForwardType, dwForwardAge, dwForwardNextHopAS, dwForwardMetric1, dwForwardMetric2, dwForwardMetric3, dwForwardMetric4, and dwForwardMetric5.

To create a new route in the IP routing table, use the CreateIpForwardEntry function. To retrieve the IP routing table, call the GetIpForwardTable function.

Example Code

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.

Note

Executing this code will change your IP routing tables and will likely cause network activity to fail.

// #ifndef WIN32_LEAN_AND_MEAN
// #define WIN32_LEAN_AND_MEAN
// #endif

// #pragma warning(push)
// #pragma warning(disable: 4127)

// #include <windows.h>

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
/* Note: could also use malloc() and free() */

int main()
{

    // 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);
}

Requirements

Header

iphlpapi.h

Library

Iphlpapi.lib

See Also

Reference

IP Helper Functions
CreateIpForwardEntry
DeleteIpForwardEntry
GetIpForwardTable
GetIpInterfaceEntry
MIB_IPINTERFACE_ROW
MIB_IPFORWARDROW

Other Resources

IP Helper