Route Tables

The basis for delivering data packets over the Internet Protocol (IP) is the route table. The IP route table contains addresses for various destinations on the network, and enables the stack to search the table for the best way to reach a specific host on the Internet. For more detailed information about how TCP/IP routing works and is managed, I recommend that you read RFC 1354, "IP Forwarding Table MIB."

To look at a device's IP route table, you simply need to call the GetIpForwardTable() function:

DWORD GetIpForwardTable(MIB_IPFORWARDTABLE *pIpForwardTable,
   ULONG *pdwSize, BOOL bOrder);

The first parameter, pIpForwardTable, is a pointer to a buffer that receives the route table when the function returns. The pdwSize parameter should point to a ULONG variable that specifies the size, in bytes, of the pIpForwardTable buffer. Finally, if you want to sort the route table by destination IP address, set the bOrder flag to TRUE.

The route table is defined by the MIB_IPFORWARDTABLE structure, and looks like the following:

typedef struct _MIB_IPFORWARDTABLE {
   DWORD dwNumEntries;

The MIB_IPFORWARDTABLE structure contains some basic information about the route table. The first field, dwNumEntries, indicates the total number of MIB_IPFORWARDROW items in the route table array. The actual routing entry information is stored in the table parameter.

Each route table entry is specified by a MIB_IPFORWARDROW structure:

typedef struct _MIB_IPFORWARDROW {
   DWORD dwForwardDest;
   DWORD dwForwardMask;
   DWORD dwForwardPolicy;
   DWORD dwForwardNextHop;
   DWORD dwForwardIfIndex;
   DWORD dwForwardType;
   DWORD dwForwardProto;
   DWORD dwForwardAge;
   DWORD dwForwardNextHopAS;
   DWORD dwForwardMetric1;
   DWORD dwForwardMetric2;
   DWORD dwForwardMetric3;
   DWORD dwForwardMetric4;
   DWORD dwForwardMetric5;

Table 3.8 describes the fields of the MIB_IPFORWARDROW structure.

Table 3.8. MIB_IPFORWARDROW Field Descriptions




The IP address of the destination.


The subnet mask of the destination address.




The IP address of the next hop in the route.


The index of the interface for this route.


The route type, which can be one of the following:






The protocol that generated the route (see Table 3.9).


The age of the route, in seconds.


The autonomous system number of the net hop.


A routing-protocol-specific metric value. See RFC 1354 for more information.


A routing-protocol-specific metric value. See RFC 1354 for more information.


A routing-protocol-specific metric value. See RFC 1354 for more information.


A routing-protocol-specific metric value. See RFC 1354 for more information.


A routing-protocol-specific metric value. See RFC 1354 for more information.

Table 3.9. IP Route Forwarding Protocols




Protocol not specified


Local interface


Static route


Result of an ICMP redirect


Exterior Gateway Protocol


Gateway-Gateway Protocol


FuzzBall HelloSpeak protocol


Berkeley RIP or RIP-II protocol


Dual IS-IS protocol


ISO 9542 protocol


Cisco IGRP protocol


BBN SPF IGP protocol


Open Shortest Path First protocol


Border Gateway Protocol


Routes that were originally added by a routing protocol and are not static


Static routes


Static routes that do not cause Dial on Demand

Route Table Entries

The IPHelper API functions also give you the capability to create, delete, or modify route table entries.

To create a new entry in the route table, you must first completely fill out a MIB_IPFORWARDROW structure. In order to successfully create a route, you must also specify that the new route will use the PROTO_IP_NETMGMT route protocol, by setting it in the dwForwardProto field before calling CreateIpForwardEntry():

DWORD CreateIpForwardEntry(MIB_IPFORWARDROW *pRoute);

The only parameter required is a pointer to the new route structure.

If you want to modify an existing route entry, call SetIpForwardEntry():

DWORD SetIpForwardEntry(MIB_IPFORWARDROW *pRoute);

Once again, this function needs only a pointer to a MIB_IPFORWARDROW structure passed in for its pRoute parameter. You must also specify the dwForwardIndex, dwForwardDest, dwForwardMask, and dwForwardNextHop parameters. In addition, you must use PROTO_IP_NETMGMT for the dwForwardProto member.

To delete a route entry, call DeleteIpForwardEntry():

DWORD DeleteIpForwardEntry(MIB_IPFORWARDROW *pRoute);

The only parameter that the function needs to successfully delete a route entry is a pointer to a IPFORWARDROW structure. The structure should be configured in the same manner as you configured the SetIpForwardEntry() function.

Route Support Functions

In addition to manipulating and reading the route table, some router management functions enable you to get more information about how data packets are routed over the network. To find out the route table entry that describes the best route to a specific IP address, call the GetBestRoute() function:

DWORD GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,

The dwDestAddr and dwSourceAddr parameters specify the source and destination IP addresses. When the function returns, the MIB_IPFORWARDROW buffer that is pointed to by the pBestRoute parameter is filled in with details about the best route from the source to the destination addresses.

Finding out the best interface for the route to a particular address is accomplished with the GetBestInterface() function:

DWORD GetBestInterface(IPAddr dwDestAddr, DWORD *pdwBestIfIndex);

Here, you pass in the dwDestAttr parameter, which is the destination IP address and a pointer to a DWORD buffer. When the function returns, it will place the index of the best route interface in the pdwBestIfIndex buffer.

The last piece of information you can get from the route functions is the total round trip time (RTT) and hop count to a particular destination address. You can determine this information by calling the following:

BOOL GetRTTAndHopCount(IPAddr DestIpAddress, ULONG *HopCount,
   ULONG MaxHops, ULONG *RTT);

The DestIpAddress parameter tells the route table the destination address for which it needs to calculate the RTT and hop count. HopCount points to a ULONG variable that contains the hop count when the function returns. This is followed by MaxHops, which you should specify the maximum number of hops to search. Finally, the RTT parameter is a pointer to a ULONG buffer that will get the round trip time, in milliseconds, when the function completes.