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:
Protocol
should be within range 1-14 (almost non entry has such value)Luid.IfType
shouldn't be 0 (again almost all are zero)Prefix
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.
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.