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。
如果函式失敗,傳回值就是下列其中一個錯誤碼。
傳回碼 | Description |
---|---|
|
存取遭到拒絕。 Windows Vista 和 Windows Server 2008 上傳回此錯誤的數個條件如下:使用者缺少本機電腦上的必要系統管理許可權,或應用程式未在增強的殼層中執行,因為內建系統管理員 (RunAs 系統管理員) 。 |
|
系統找不到指定的檔案。 如果找不到 pRoute 參數所指向之 MIB_IPFORWARDROW 結構之 dwForwardIfIndex 成員所指定的網路介面,則會在 Windows Vista 上傳回此錯誤。 |
|
pRoute 參數為 NULL,或 SetIpForwardEntry 無法從 pRoute 所指向的記憶體讀取,或MIB_IPFORWARDROW結構的其中一個成員無效。 |
|
找不到專案。 當 DeleteIpForwardEntry 函式和 SetIpForwardEntry 函式針對相同的 IPv4 路由表專案呼叫 SetIpForwardEntry 函式時,就會在 Windows Vista 和更新版本上傳回此錯誤。 |
|
不支援此要求。 如果未在本機計算機上設定IPv4傳輸,則會傳回此值。 如果本機計算機上未設定 TCP/IP 堆棧,Windows Server 2003 和更早版本也會傳回此錯誤。 |
|
使用 FormatMessage 取得傳回錯誤的訊息字串。 |
備註
路由參數所指向之MIB_IPFORWARDROW結構的 dwForwardProto 成員必須設定為 MIB_IPPROTO_NETMGMT否則 SetIpForwardEntry 將會失敗。 路由通訊協定標識碼可用來識別指定路由通訊協定的路由資訊。 例如,MIB_IPPROTO_NETMGMT可用來識別透過網路管理所設定IP路由的路由資訊,例如動態主機設定通訊協定 (DHCP) 、簡單網路管理通訊協定 (SNMP) ,或透過呼叫 CreateIpForwardEntry、DeleteIpForwardEntry 或 SetIpForwardEntry 函式。
在 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 修改的路由會自動有 INFINITE 的 dwForwardAge 預設值。
SetIpForwardEntry 目前不會使用路由參數所指向之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,否則此呼叫將會失敗。 如果應用程式缺少此指令清單檔,則身為系統管理員以外的 Administrators 群組成員登入的使用者,就必須在增強殼層中執行應用程式,因為內建系統管理員 (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 專業版 [僅限傳統型應用程式] |
最低支援的伺服器 | Windows 2000 Server [僅限傳統型應用程式] |
目標平台 | Windows |
標頭 | iphlpapi.h |
程式庫 | Iphlpapi.lib |
Dll | Iphlpapi.dll |