This sample shows how to get the interface metric for an interface with a given interface index, using
GetIpInterfaceEntry with P/Invoke. The forward route metric for
CreateIPForwardEntry on Vista/Server 2008 is then calculated by finding the offset, i.e., gateway cost metric, and adding with the interface metric.
My application which adds new routes to the routing table was working fine until I shifted to Windows 2008.
CreateIPForwardEntry was retuning me an invalid parameter. Then, with some research and Googling, I found that there is actually a breaking API change with
CreateIPForwardEntry, which was not well documented.
On Windows Vista and Windows Server 2008 (
WINVER >= 0x0600), the route metric specified in the
dwForwardMetric1 member of the
MIB_IPFORWARDROW structure should be equal to or greater than the metric member of the associated
MIB_IPINTERFACE_ROW structure. An application can retrieve the interface metric by calling the
GetIpInterfaceEntry function. But, I had given 1 for
dwForwardMetric1, which was not working. So, it was required to find the interface metric to calculate the value
Using the code
This sample does not illustrate how to get the interface index for a destination using
GetBestInterface. Currently, my machine’s interface index is used. Also, there is no code included for creating routes using
CreateIpForwardEntry. A WMI query is used to get the gateway metric.
uint interfaceIndex = 9;
MIB_IPINTERFACE_ROW aRow = new MIB_IPINTERFACE_ROW();
aRow.Family = 2;
aRow.InterfaceLuid = 0;
aRow.InterfaceIndex = interfaceIndex;
uint errorCode = GetIpInterfaceEntry(ref aRow);
if (errorCode != 0)
throw new Exception("some error");
uint forwardMetric = aRow.Metric;
ManagementObjectSearcher query =
new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration" +
" WHERE IPEnabled = 'TRUE' and InterfaceIndex='" +
interfaceIndex.ToString() + "'");
ManagementObjectCollection queryCollection = query.Get();
foreach (ManagementObject tempMObj in queryCollection)
UInt16 getwayCostMetric = tempMObj["GatewayCostMetric"] as UInt16;
if (getwayCostMetric != null && getwayCostMetric.Length > 0)
forwardMetric += getwayCostMetric;
Points of interest
GatewayCostMetric or the offset we are calculating will not be available for a network interface with no default gateway configured.
Also, I had some problem initially in marshalling the
MIB_IPINTERFACE_ROW structure because strangely,
NL_INTERFACE_OFFLOAD_ROD described in MSDN is different from what is declared in nldef.h.