Click here to Skip to main content
Click here to Skip to main content
Go to top

Using GetIpInterfaceEntry with P/Invoke for getting an interface metric

, 22 Aug 2008
Rate this:
Please Sign up or sign in to vote.
Using GetIpInterfaceEntry to get an interface metric, and then calculating dwForwardMetric1 for creating routes in Vista/Windows Server 2008.

Introduction

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.

Background

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 fordwForwardMetric1.

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.

//From GetBestInterface for a destination
uint interfaceIndex = 9;
//So we query for the interface with 
//the interface index got from GetBestInterface 
MIB_IPINTERFACE_ROW aRow = new MIB_IPINTERFACE_ROW(); 
aRow.Family = 2; 
aRow.InterfaceLuid = 0;
aRow.InterfaceIndex = interfaceIndex; 
//GetIpInterfaceEntry is available in Vista/2008 server or higher 
uint errorCode = GetIpInterfaceEntry(ref aRow); 
if (errorCode != 0) 
{ 
    throw new Exception("some error"); 
} 

uint forwardMetric = aRow.Metric;
//Now we calculate the offset metric from 
//the Gateway configured for this interface
ManagementObjectSearcher query = 
  new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration" + 
  " WHERE IPEnabled = 'TRUE' and InterfaceIndex='" + 
  interfaceIndex.ToString() + "'");
ManagementObjectCollection queryCollection = query.Get(); 
foreach (ManagementObject tempMObj in queryCollection) 
{ 
    //Then we get the GatewayCostMetric and add it with Interface Metric; 
    UInt16[] getwayCostMetric = tempMObj["GatewayCostMetric"] as UInt16[]; 
    //if not default gateway configured then this will be null
    if (getwayCostMetric != null && getwayCostMetric.Length > 0) 
    { 
    //we interface metic and offset
    forwardMetric += getwayCostMetric[0]; 
    } 

}
//This forwardMetric can be used for Creating routes 
//using CreateIPForwardEntry in Vista/ Windows Server 2008

Points of interest

The 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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gautham Jayaraman
Software Developer Working for an MNC
India India
Working for an MNC for last 5 years. Currently in application development, mainly ASP.NET. Has also worked with internet security and penetration testing. MCSD .NET certified. Enjoys travelling and food.

Comments and Discussions

 
Questionbreak ? PinmemberZike8-Aug-09 1:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 22 Aug 2008
Article Copyright 2008 by Gautham Jayaraman
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid