setIpForwardEntry 函数 (iphlpapi.h)
SetIpForwardEntry 函数修改本地计算机的 IPv4 路由表中的现有路由。
语法
IPHLPAPI_DLL_LINKAGE DWORD SetIpForwardEntry(
[in] PMIB_IPFORWARDROW pRoute
);
参数
[in] pRoute
指向 MIB_IPFORWARDROW 结构的指针,该结构指定现有路由的新信息。 调用方必须为此结构的 dwForwardProto 成员指定MIB_IPPROTO_NETMGMT。 调用方还必须为结构的 dwForwardIfIndex、 dwForwardDest、 dwForwardMask、 dwForwardNextHop 和 dwForwardPolicy 成员指定值。
返回值
如果函数成功,则返回值NO_ERROR。
如果函数失败,则返回值为以下错误代码之一。
返回代码 | 说明 |
---|---|
|
访问被拒绝。 此错误在 Windows Vista 和 Windows Server 2008 上返回,条件如下:用户在本地计算机上缺少所需的管理权限,或者应用程序未在增强的 shell 中运行,因为内置管理员 (RunAs 管理员) 。 |
|
系统找不到指定的文件。 如果找不到由 pRoute 参数指向的MIB_IPFORWARDROW结构的 dwForwardIfIndex 成员指定的网络接口,则会在 Windows Vista 及更高版本上返回此错误。 |
|
pRoute 参数为 NULL,或者 SetIpForwardEntry 无法从 pRoute 指向的内存中读取,或者 MIB_IPFORWARDROW 结构的某个成员无效。 |
|
找不到 元素。 当为同一 IPv4 路由表条目调用 DeleteIpForwardEntry 函数和 SetIpForwardEntry 函数时,将在 Windows Vista 和更高版本上返回错误。 |
|
不支持该请求。 如果未在本地计算机上配置 IPv4 传输,则返回此值。 如果未在本地计算机上配置 TCP/IP 堆栈,则 Windows Server 2003 及更早版本也会返回此错误。 |
|
使用 FormatMessage 获取返回错误的消息字符串。 |
注解
路由参数指向的 MIB_IPFORWARDROW 结构的 dwForwardProto 成员必须设置为 MIB_IPPROTO_NETMGMT否则 SetIpForwardEntry 将失败。 路由协议标识符用于标识指定路由协议的路由信息。 例如,MIB_IPPROTO_NETMGMT用于通过网络管理(例如动态主机配置协议 (DHCP) 、简单网络管理协议 (SNMP) 或通过调用 CreateIpForwardEntry、DeleteIpForwardEntry 或 SetIpForwardEntry 函数)来标识 IP 路由集的路由信息。
在 Windows Vista 和 Windows Server 2008 上,pRoute 参数指向的 MIB_IPFORWARDROW 结构的 dwForwardMetric1 成员中指定的路由指标表示添加到关联接口MIB_IPINTERFACE_ROW结构的指标成员中指定的接口指标的组合。 因此,MIB_IPFORWARDROW 结构的 dwForwardMetric1 成员应等于或大于关联MIB_IPINTERFACE_ROW结构的 Metric 成员。 如果应用程序想要将路由指标设置为 0,则应将 MIB_IPFORWARDROW 结构的 dwForwardMetric1 成员设置为等于关联MIB_IPINTERFACE_ROW结构的 Metric 成员中指定的接口指标值。 应用程序可以通过调用 GetIpInterfaceEntry 函数来检索接口指标。
在 Windows Vista 和 Windows Server 2008 上, SetIpForwardEntry 函数仅适用于具有单个子接口的接口 (其中接口 LUID 和子接口 LUID 是相同的) 。 MIB_IPFORWARDROW 结构的 dwForwardIfIndex 成员指定接口。
setIpForwardEntry 当前不使用路由参数指向的MIB_IPFORWARDROW结构 dwForwardAge 成员。 仅当路由和远程访问服务 (RRAS) 正在运行时,才使用 dwForwardAge 成员,然后仅对协议标识符引用页上定义的 MIB_IPPROTO_NETMGMT 类型的路由使用。 当 dwForwardAge 设置为 INFINITE 时,不会根据超时删除路由
值。 dwForwardAge 的任何其他值指定 TCP/IP 堆栈从网络路由表中删除路由之前的秒数。
由 SetIpForwardEntry 修改的路由将自动将 dwForwardAge 的默认值设置为 INFINITE。
setIpForwardEntry 当前不使用 route 参数指向的 MIB_IPFORWARDROW 结构中的许多成员。 这些成员包括 dwForwardPolicy、 dwForwardType、 dwForwardAge、 dwForwardNextHopAS、 dwForwardMetric1、 dwForwardMetric2、 dwForwardMetric3、 dwForwardMetric4 和 dwForwardMetric5。
若要在 IP 路由表中创建新路由,请使用 CreateIpForwardEntry 函数。 若要检索 IP 路由表,请调用 GetIpForwardTable 函数。
在 Windows Vista 及更高版本中, SetIpForwardEntry 函数只能由以 Administrators 组成员身份登录的用户调用。 如果 SetIpForwardEntry 由不是 Administrators 组成员的用户调用,则函数调用将失败并返回 ERROR_ACCESS_DENIED 。
此函数也可能因为 Windows Vista 及更高版本上的用户帐户控制 (UAC) 而失败。 如果包含此函数的应用程序由以管理员组成员身份登录(而不是内置管理员)的用户执行,则此调用将失败,除非应用程序已在清单文件中标记为 requestedExecutionLevel 设置为 requireAdministrator。 如果应用程序缺少此清单文件,则作为管理员组成员(而不是内置管理员)登录的用户必须在增强的 shell 中执行应用程序,因为内置管理员 (RunAs 管理员) 此函数才能成功。
示例
以下示例演示如何将默认网关更改为 NewGateway。 只需调用 GetIpForwardTable,更改网关,然后调用 SetIpForwardEntry 不会更改路由,而只会添加新路由。 如果出于某种原因存在多个默认网关,此代码将删除它们。 请注意,新网关必须可行;否则,TCP/IP 将忽略更改。
Windows Vista 及更高版本: 在 Windows Vista 及更高版本上为同一路由表条目调用 DeleteIpForwardEntry 函数和 SetIpForwardEntry 函数时,将返回ERROR_NOT_FOUND。 在 Windows Vista 及更高版本上复制此示例的正确方法是使用 CreateIpForwardEntry 函数创建新的路由表条目,然后通过调用 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);
}
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 2000 Professional [仅限桌面应用] |
最低受支持的服务器 | Windows 2000 Server [仅限桌面应用] |
目标平台 | Windows |
标头 | iphlpapi.h |
Library | Iphlpapi.lib |
DLL | Iphlpapi.dll |