Compartir a través de


Función SetIpForwardEntry (iphlpapi.h)

La función SetIpForwardEntry modifica una ruta existente en la tabla de enrutamiento IPv4 del equipo local.

Sintaxis

IPHLPAPI_DLL_LINKAGE DWORD SetIpForwardEntry(
  [in] PMIB_IPFORWARDROW pRoute
);

Parámetros

[in] pRoute

Puntero a una estructura de MIB_IPFORWARDROW que especifica la nueva información de la ruta existente. El autor de la llamada debe especificar MIB_IPPROTO_NETMGMT para el miembro dwForwardProto de esta estructura. El llamador también debe especificar valores para los miembros dwForwardIfIndex, dwForwardDest, dwForwardMask, dwForwardNextHop y dwForwardPolicy de la estructura.

Valor devuelto

Si la función se ejecuta correctamente, el valor devuelto es NO_ERROR.

Si se produce un error en la función, el valor devuelto es uno de los siguientes códigos de error.

Código devuelto Descripción
ERROR_ACCESS_DENIED
Acceso denegado. Este error se devuelve en Windows Vista y Windows Server 2008 en varias condiciones que incluyen lo siguiente: el usuario carece de los privilegios administrativos necesarios en el equipo local o la aplicación no se ejecuta en un shell mejorado como administrador integrado (administrador de RunAs).
ERROR_FILE_NOT_FOUND
El sistema no encuentra el archivo especificado. Este error se devuelve en Windows Vista y versiones posteriores si no se encontró la interfaz de red especificada por el miembro dwForwardIfIndex de la estructura de MIB_IPFORWARDROW a la que apunta el parámetro pRoute .
ERROR_INVALID_PARAMETER
El parámetro pRoute es NULL o SetIpForwardEntry no puede leer desde la memoria a la que apunta pRoute o uno de los miembros de la estructura MIB_IPFORWARDROW no es válido.
ERROR_NOT_FOUND
No se encuentra el elemento . El error se devuelve en Windows Vista y versiones posteriores cuando se llama a la función DeleteIpForwardEntry y, a continuación, se llama a la función SetIpForwardEntry para la misma entrada de tabla de rutas IPv4.
ERROR_NOT_SUPPORTED
No se admite la solicitud. Este valor se devuelve si el transporte IPv4 no está configurado en el equipo local. Este error también se devuelve en Windows Server 2003 y versiones anteriores si no hay ninguna pila TCP/IP configurada en el equipo local.
Otros
Use FormatMessage para obtener la cadena de mensaje para el error devuelto.

Comentarios

El miembro dwForwardProto de MIB_IPFORWARDROW estructura a la que apunta el parámetro de ruta debe establecerse en MIB_IPPROTO_NETMGMT de lo contrario, se producirá un error en SetIpForwardEntry . Los identificadores de protocolo de enrutamiento se usan para identificar la información de ruta del protocolo de enrutamiento especificado. Por ejemplo, MIB_IPPROTO_NETMGMT se usa para identificar información de ruta para el enrutamiento IP establecido a través de la administración de red, como el Protocolo de configuración dinámica de host (DHCP), el Protocolo de administración de red simple (SNMP) o mediante llamadas a las funciones CreateIpForwardEntry, DeleteIpForwardEntry o SetIpForwardEntry .

En Windows Vista y Windows Server 2008, la métrica de ruta especificada en el miembro dwForwardMetric1 de la estructura de MIB_IPFORWARDROW a la que apunta el parámetro pRoute representa una combinación de la métrica de ruta agregada a la métrica de interfaz especificada en el miembro Metric de la estructura MIB_IPINTERFACE_ROW de la interfaz asociada. Por lo tanto, el miembro dwForwardMetric1 de la estructura MIB_IPFORWARDROW debe ser igual o mayor que el miembro Metric de la estructura de MIB_IPINTERFACE_ROW asociada. Si una aplicación desea establecer la métrica de ruta en 0, el miembro dwForwardMetric1 de la estructura de MIB_IPFORWARDROW debe establecerse igual al valor de la métrica de interfaz especificada en el miembro Metric de la estructura de MIB_IPINTERFACE_ROW asociada. Una aplicación puede recuperar la métrica de interfaz llamando a la función GetIpInterfaceEntry .

En Windows Vista y Windows Server 2008, la función SetIpForwardEntry solo funciona en interfaces con una sola subfase (donde el LUID de interfaz y el LUID de subinterfacio son los mismos). El miembro dwForwardIfIndex de la estructura MIB_IPFORWARDROW especifica la interfaz.

El miembro dwForwardAge a la estructura de MIB_IPFORWARDROW a la que apunta el parámetro route no lo usa Actualmente SetIpForwardEntry. El miembro dwForwardAge solo se usa si se está ejecutando el servicio de enrutamiento y acceso remoto (RRAS) y, a continuación, solo para las rutas de tipo MIB_IPPROTO_NETMGMT tal como se define en la página de referencia identificadores de protocolo . Cuando dwForwardAge se establece en INFINITE, la ruta no se quitará en función de un tiempo de espera.

. Cualquier otro valor de dwForwardAge especifica el número de segundos hasta que la pila TCP/IP quite la ruta de la tabla de enrutamiento de red.

Una ruta modificada por SetIpForwardEntry tendrá automáticamente un valor predeterminado para dwForwardAge de INFINITE.

SetIpForwardEntry no usa actualmente varios miembros de la estructura MIB_IPFORWARDROW a la que apunta el parámetro route. Estos miembros incluyen dwForwardPolicy, dwForwardType, dwForwardAge, dwForwardNextHopAS, dwForwardMetric1, dwForwardMetric2, dwForwardMetric3, dwForwardMetric4 y dwForwardMetric5.

Para crear una nueva ruta en la tabla de enrutamiento IP, use la función CreateIpForwardEntry . Para recuperar la tabla de enrutamiento IP, llame a la función GetIpForwardTable .

En Windows Vista y versiones posteriores, un usuario que inició sesión como miembro del grupo Administradores solo puede llamar a la función SetIpForwardEntry . Si un usuario llama a SetIpForwardEntry que no es miembro del grupo Administradores, se producirá un error en la llamada de función y se devolverá ERROR_ACCESS_DENIED .

Esta función también puede producir un error debido al control de cuentas de usuario (UAC) en Windows Vista y versiones posteriores. Si un usuario que ha iniciado sesión como miembro del grupo Administradores que no sea el administrador integrado ejecuta esta función, se producirá un error en esta llamada a menos que la aplicación se haya marcado en el archivo de manifiesto con un valor requestedExecutionLevel establecido en requireAdministrator. Si la aplicación carece de este archivo de manifiesto, un usuario que inició sesión como miembro del grupo Administradores distinto del administrador integrado debe ejecutar la aplicación en un shell mejorado como administrador integrado (administrador de runas) para que esta función se realice correctamente.

Nota En Windows NT 4.0 y Windows 2000 y versiones posteriores, esta función ejecuta una operación con privilegios. Para que esta función se ejecute correctamente, el autor de la llamada debe iniciar sesión como miembro del grupo Administradores o del grupo NetworkConfigurationOperators.
 

Ejemplos

En el ejemplo siguiente se muestra cómo cambiar la puerta de enlace predeterminada a NewGateway. Simplemente llamando a GetIpForwardTable, cambiando la puerta de enlace y llamando a SetIpForwardEntry no cambiará la ruta, sino que simplemente agregará una nueva. Si por algún motivo hay varias puertas de enlace predeterminadas presentes, este código los eliminará. Tenga en cuenta que la nueva puerta de enlace debe ser viable; de lo contrario, TCP/IP omitirá el cambio.

Nota La ejecución de este código cambiará las tablas de enrutamiento IP y probablemente provocará un error en la actividad de red.
 

Windows Vista y versiones posteriores: Cuando se llama a la función DeleteIpForwardEntry y, a continuación, se llama a la función SetIpForwardEntry para la misma entrada de tabla de rutas en Windows Vista y versiones posteriores, se devuelve ERROR_NOT_FOUND. La manera adecuada de replicar este ejemplo en Windows Vista y versiones posteriores es usar la función CreateIpForwardEntry para crear la nueva entrada de tabla de rutas y, a continuación, eliminar la entrada de tabla de rutas antigua llamando a la función DeleteIpForwardEntry .

#pragma comment(lib, "IPHLPAPI.lib")

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


Requisitos

Requisito Value
Cliente mínimo compatible Windows 2000 Professional [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows 2000 Server [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado iphlpapi.h
Library Iphlpapi.lib
Archivo DLL Iphlpapi.dll

Consulte también

CreateIpForwardEntry

DeleteIpForwardEntry

GetIpForwardTable

GetIpInterfaceEntry

Referencia de la función auxiliar de IP

Página de inicio del asistente de IP

MIB_IPFORWARDROW

MIB_IPINTERFACE_ROW