kernel-iph: Implement get_nexthop()
authorMartin Willi <martin@revosec.ch>
Thu, 12 Dec 2013 16:34:06 +0000 (17:34 +0100)
committerMartin Willi <martin@revosec.ch>
Wed, 4 Jun 2014 14:32:08 +0000 (16:32 +0200)
src/libcharon/plugins/kernel_iph/kernel_iph_net.c

index 56c458f..36e3c4c 100644 (file)
@@ -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;
 }