cwindowsrouteswindows-networkingiphelper

List windows route table


I want to list entries from windows route table. Same output as from route print. I use GetIpForwardTable2 function from IP Helper API. But I get some weird results which differ from route command output. I run it in Windows 7 64bit in VirtualBox where I have 3 network cards (NAT, Bridge and Internal Network) and compile it under cygwin with following command:

gcc -D_WIN32_WINNT=0x0601 -DNTDDI_VERSION=0x06010000 win-iproute.c -liphlpapi

Those _WIN32_WINNT and NTDDI_VERSION are just to make functionality from Win7 available. To make it simplier I consider ipv4 only now.

Here is the code:

#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <Mstcpip.h>

#include <stdio.h>

int main(int argc, char *argv[])
{
  DWORD retval;
  MIB_IPFORWARD_TABLE2 *routes = NULL;
  MIB_IPFORWARD_ROW2 *route;
  int idx;

  retval = GetIpForwardTable2(AF_INET, &routes);
  if (retval != ERROR_SUCCESS)
  {
    fprintf(stderr, "GetIpForwardTable2 failed (0x%x)\n.", retval);
    return 1;
  }

  printf("Route entries count: %lu\n", routes->NumEntries);

  for (idx = 0; idx < routes->NumEntries; idx++)
  {
    printf("\n -- Entry #%d -- \n", idx);
    route = routes->Table + idx;
    printf("luid: \t\t Reserved: %u, NetLuidIndex %u, IfType %u\n",
      route->InterfaceLuid.Info.Reserved,
      route->InterfaceLuid.Info.NetLuidIndex,
      route->InterfaceLuid.Info.IfType);
    printf("protocol: \t %lu\n", route->Protocol);
    printf("origin: \t %lu\n", route->Origin);
    printf("loopback: \t %lu\n", route->Loopback);
    printf("next hop: \t %s\n", inet_ntoa(route->NextHop.Ipv4.sin_addr));
    printf("site prefix length: \t %u\n", route->SitePrefixLength);
    printf("prefix length: \t %u\n", route->DestinationPrefix.PrefixLength);
    printf("prefix : \t %s\n", inet_ntoa(route->DestinationPrefix.Prefix.Ipv4.sin_addr));
  }

  return 0;
}

And the output is:

Route entries count: 22

 -- Entry #0 --
luid:            Reserved: 0, NetLuidIndex 6, IfType 6
protocol:        0
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   0
prefix :         0.0.0.0

 -- Entry #1 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        0
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   3
prefix :         0.0.0.0

 -- Entry #2 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        4294967295
origin:          257
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   10
prefix :         0.1.0.0

 -- Entry #3 --
luid:            Reserved: 17, NetLuidIndex 0, IfType 0
protocol:        11
origin:          0
loopback:        2
next hop:        0.0.0.0
site prefix length:      17
prefix length:   0
prefix :         2.0.0.0

 -- Entry #4 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        32
origin:          0
loopback:        2
next hop:        0.1.0.0
site prefix length:      0
prefix length:   255
prefix :         2.0.0.0

 -- Entry #5 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        0
origin:          256
loopback:        255
next hop:        0.0.0.0
site prefix length:      0
prefix length:   11
prefix :         255.255.255.255

 -- Entry #6 --
luid:            Reserved: 3, NetLuidIndex 65792, IfType 0
protocol:        201326592
origin:          2
loopback:        0
next hop:        0.0.0.0
site prefix length:      3
prefix length:   24
prefix :         0.0.6.0

 -- Entry #7 --
luid:            Reserved: 5855577, NetLuidIndex 89, IfType 0
protocol:        0
origin:          2
loopback:        0
next hop:        0.1.0.0
site prefix length:      89
prefix length:   0
prefix :         0.0.0.0

 -- Entry #8 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        0
origin:          4294967295
loopback:        0
next hop:        2.0.0.0
site prefix length:      0
prefix length:   0
prefix :         0.0.0.0

 -- Entry #9 --
luid:            Reserved: 16777215, NetLuidIndex 65791, IfType 0
protocol:        593
origin:          1572864
loopback:        0
next hop:        2.0.0.0
site prefix length:      255
prefix length:   0
prefix :         0.0.0.0

 -- Entry #10 --
luid:            Reserved: 1, NetLuidIndex 512, IfType 0
protocol:        0
origin:          0
loopback:        0
next hop:        255.255.255.255
site prefix length:      1
prefix length:   0
prefix :         0.0.0.0

 -- Entry #11 --
luid:            Reserved: 4, NetLuidIndex 512, IfType 0
protocol:        0
origin:          0
loopback:        0
next hop:        0.0.6.0
site prefix length:      4
prefix length:   81
prefix :         0.0.0.0

 -- Entry #12 --
luid:            Reserved: 0, NetLuidIndex 16776960, IfType 65535
protocol:        3
origin:          1
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   0
prefix :         0.1.0.0

 -- Entry #13 --
luid:            Reserved: 0, NetLuidIndex 12, IfType 6
protocol:        4294967295
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   0
prefix :         0.0.0.0

 -- Entry #14 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        0
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   3
prefix :         0.0.0.0

 -- Entry #15 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        4294967295
origin:          257
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   255
prefix :         0.1.0.0

 -- Entry #16 --
luid:            Reserved: 585, NetLuidIndex 0, IfType 0
protocol:        3449440
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      73
prefix length:   0
prefix :         2.0.0.0

 -- Entry #17 --
luid:            Reserved: 3211321, NetLuidIndex 13056, IfType 65
protocol:        3342403
origin:          4325427
loopback:        49
next hop:        125.0.0.0
site prefix length:      53
prefix length:   68
prefix :         54.0.45.0

 -- Entry #18 --
luid:            Reserved: 3473453, NetLuidIndex 17408, IfType 54
protocol:        0
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      0
prefix length:   0
prefix :         70.0.69.0

 -- Entry #19 --
luid:            Reserved: 0, NetLuidIndex 0, IfType 0
protocol:        7471205
origin:          7274610
loopback:        0
next hop:        115.0.97.0
site prefix length:      111
prefix length:   0
prefix :         0.0.0.0

 -- Entry #20 --
luid:            Reserved: 7274611, NetLuidIndex 26112, IfType 116
protocol:        3277144
origin:          50725
loopback:        0
next hop:        49.69.55.56
site prefix length:      51
prefix length:   56
prefix :         65.0.100.0

 -- Entry #21 --
luid:            Reserved: 3277144, NetLuidIndex 0, IfType 0
protocol:        0
origin:          0
loopback:        0
next hop:        0.0.0.0
site prefix length:      192
prefix length:   0
prefix :         16.0.0.0

While the output of route print -4 is following:

===========================================================================
Interface List
 16...08 00 27 7e 98 16 ......Intel(R) PRO/1000 MT Desktop Adapter #3
 14...08 00 27 86 3d 31 ......Intel(R) PRO/1000 MT Desktop Adapter #2
 11...08 00 27 42 d2 16 ......Intel(R) PRO/1000 MT Desktop Adapter
  1...........................Software Loopback Interface 1
 12...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter
 13...00 00 00 00 00 00 00 e0 Teredo Tunneling Pseudo-Interface
 15...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #2
 17...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #3
===========================================================================

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0         10.0.2.2        10.0.2.15     10
          0.0.0.0          0.0.0.0       10.0.0.138        10.0.0.36     10
         10.0.0.0    255.255.255.0         On-link         10.0.0.36    266
        10.0.0.36  255.255.255.255         On-link         10.0.0.36    266
       10.0.0.255  255.255.255.255         On-link         10.0.0.36    266
         10.0.2.0    255.255.255.0         On-link         10.0.2.15    266
        10.0.2.15  255.255.255.255         On-link         10.0.2.15    266
       10.0.2.255  255.255.255.255         On-link         10.0.2.15    266
       89.89.89.0    255.255.255.0         On-link       89.89.89.89    266
      89.89.89.89  255.255.255.255         On-link       89.89.89.89    266
     89.89.89.255  255.255.255.255         On-link       89.89.89.89    266
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    306
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    306
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    306
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    306
        224.0.0.0        240.0.0.0         On-link         10.0.2.15    266
        224.0.0.0        240.0.0.0         On-link         10.0.0.36    266
        224.0.0.0        240.0.0.0         On-link       89.89.89.89    266
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    306
  255.255.255.255  255.255.255.255         On-link         10.0.2.15    266
  255.255.255.255  255.255.255.255         On-link         10.0.0.36    266
  255.255.255.255  255.255.255.255         On-link       89.89.89.89    266
===========================================================================
Persistent Routes:
  None

There is a lot of weird stuff in the code output. Many entries have undocumented values, for example:

It's described here MIB_IPFORWARD_ROW2 and here NET_LUID

Should I just ignore those with invalid values? and if so where are the valid ones? Or am I doing something terribly wrong?

I also discovered that when I start Windows with cables unplugged it gives less entries (which makes sense). Then I plug in the cables and entries are added. But when I unplug again they are still there. route command works as expected, when cable is unplugged entries are reduced.

When I try older function GetIpForwardTable it works. But it doesn't support ipv6.


Solution

  • So it seems that the problem was in cygwin. When I compile the example code with Microsoft C compiler cl.ex it works as expected. And after update of cygwin it works when compiled using gcc too. Interesting is that it was enough to update the packages using cygwin installer, cygwin1.dll can remain in older version.