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;
   MIB_IPFORWARDROW table[ANY_SIZE];
}MIB_IPFORWARDTABLE, *PMIB_IPFORWARDTABLE;

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;
}MIB_IPFORWARDROW, *PMIB_IPFORWARDROW;

Table 3.8 describes the fields of the MIB_IPFORWARDROW structure.

Table 3.8. MIB_IPFORWARDROW Field Descriptions

Member

Description

dwForwardDest

The IP address of the destination.

dwForwardMask

The subnet mask of the destination address.

dwForwardPolicy

Unused.

dwForwardNextHop

The IP address of the next hop in the route.

dwForwardIfIndex

The index of the interface for this route.

dwForwardType

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

MIB_IPROUTE_TYPE_INDIRECT,

MIB_IPROUTE_TYPE_DIRECT,

MIB_IPROUTE_TYPE_INVALID, or

MIB_IPROUTE_TYPE_OTHER.

dwForwardProto

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

dwForwardAge

The age of the route, in seconds.

dwForwardNextHopAS

The autonomous system number of the net hop.

dwForwardMetric1

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

dwForwardMetric2

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

dwForwardMetric3

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

dwForwardMetric4

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

dwForwardMetric5

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

Table 3.9. IP Route Forwarding Protocols

Protocol

Description

MIB_IPPROTO_OTHER

Protocol not specified

MIB_IPPROTO_LOCAL

Local interface

MIB_IPPROTO_NETMGMT

Static route

MIB_IPPROTO_ICMP

Result of an ICMP redirect

MIB_IPPROTO_EGP

Exterior Gateway Protocol

MIB_IPPROTO_GGP

Gateway-Gateway Protocol

MIB_IPPROTO_HELLO

FuzzBall HelloSpeak protocol

MIB_IPPROTO_RIP

Berkeley RIP or RIP-II protocol

MIB_IPPROTO_IS_IS

Dual IS-IS protocol

MIB_IPPROTO_ES_IS

ISO 9542 protocol

MIB_IPPROTO_CISCO

Cisco IGRP protocol

MIB_IPPROTO_BBN

BBN SPF IGP protocol

MIB_IPPROTO_OSPF

Open Shortest Path First protocol

MIB_IPPROTO_BGP

Border Gateway Protocol

MIB_IPPROTO_NT_AUTOSTATIC

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

MIB_IPPROTO_NT_STATIC

Static routes

MIB_IPPROTO_NT_STATIC_NON_DOD

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,
   MIB_IPFORWARDROW *pBestRoute);

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.