aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-12-12 17:34:06 +0100
committerMartin Willi <martin@revosec.ch>2014-06-04 16:32:08 +0200
commit13e18cb2fc52661152c570a5be3e7cddce388902 (patch)
tree0e722ee47db3dcfd33e9754c885ac06d6f5faa2c /src
parent0cefd9400734fea388b86d8d2a1075907f96d769 (diff)
downloadstrongswan-13e18cb2fc52661152c570a5be3e7cddce388902.tar.bz2
strongswan-13e18cb2fc52661152c570a5be3e7cddce388902.tar.xz
kernel-iph: Implement get_nexthop()
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/kernel_iph/kernel_iph_net.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c
index 56c458fdb..36e3c4c56 100644
--- a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c
+++ b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c
@@ -497,6 +497,38 @@ METHOD(kernel_net_t, get_source_addr, host_t*,
METHOD(kernel_net_t, get_nexthop, host_t*,
private_kernel_iph_net_t *this, host_t *dest, host_t *src)
{
+ MIB_IPFORWARD_ROW2 route;
+ SOCKADDR_INET best, *sai_dst, *sai_src = NULL;
+ DWORD res, index = 0;
+ host_t *nexthop;
+
+ res = GetBestInterfaceEx(dest->get_sockaddr(dest), &index);
+ if (res != NO_ERROR)
+ {
+ DBG1(DBG_KNL, "getting interface to %H failed: 0x%08x", dest, res);
+ return NULL;
+ }
+
+ sai_dst = (SOCKADDR_INET*)dest->get_sockaddr(dest);
+ if (src)
+ {
+ sai_src = (SOCKADDR_INET*)src->get_sockaddr(src);
+ }
+ res = GetBestRoute2(0, index, sai_src, sai_dst, 0, &route, &best);
+ if (res != NO_ERROR)
+ {
+ DBG2(DBG_KNL, "getting nexthop to %H failed: 0x%08x", dest, res);
+ return NULL;
+ }
+ nexthop = host_create_from_sockaddr((struct sockaddr*)&route.NextHop);
+ if (nexthop)
+ {
+ if (!nexthop->is_anyaddr(nexthop))
+ {
+ return nexthop;
+ }
+ nexthop->destroy(nexthop);
+ }
return NULL;
}