libcollectdclient: Implement if_nametoindex() for Windows.
[collectd.git] / src / libcollectdclient / network.c
index ddb3b5b..7105774 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/libcollectdclient/network.c
- * Copyright (C) 2005-2013  Florian Forster
+ * Copyright (C) 2005-2014  Florian Forster
  * Copyright (C) 2010       Max Henkel
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  *   Max Henkel <henkel at gmx.at>
  **/
 
+#if WIN32
+
+#include <winsock2.h>
+#include <wspiapi.h>
+#include <iphlpapi.h>
+#include <windows.h>
+#include <io.h>
+#include <assert.h>
+
+#else
+
 #include "collectd.h"
 
 #include <stdlib.h>
@@ -47,6 +58,8 @@
 # include <net/if.h>
 #endif
 
+#endif /* !WIN32 */
+
 #include "collectd/network.h"
 #include "collectd/network_buffer.h"
 
@@ -164,7 +177,7 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
         optname = IP_TTL;
 
       setsockopt (srv->fd, IPPROTO_IP, optname,
-          &srv->ttl,
+          (void *) &srv->ttl,
           sizeof (srv->ttl));
     }
     else if (ai_ptr->ai_family == AF_INET6)
@@ -179,7 +192,7 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
         optname = IPV6_UNICAST_HOPS;
 
       setsockopt (srv->fd, IPPROTO_IPV6, optname,
-          &srv->ttl,
+          (void *) &srv->ttl,
           sizeof (srv->ttl));
     }
 
@@ -385,15 +398,52 @@ int lcc_server_set_ttl (lcc_server_t *srv, uint8_t ttl) /* {{{ */
   return (0);
 } /* }}} int lcc_server_set_ttl */
 
-int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ */
+#if WIN32
+static unsigned if_nametoindex (LPCSTR pszIfName) /* {{{ */
+{
+  IP_ADAPTER_ADDRESSES *pAddrList;
+  IP_ADAPTER_ADDRESSES *pAddrPtr;
+  BYTE bBuffer[8192];
+  ULONG dwSize;
+  ULONG dwStatus;
+  unsigned dwIndex = 0;
+
+  dwSize = (ULONG) sizeof (bBuffer);
+  pAddrList = (IP_ADAPTER_ADDRESSES *) &bBuffer[0];
+
+  dwStatus = GetAdaptersAddresses (
+      /* Family           = */ AF_UNSPEC,
+      /* Flags            = */ GAA_FLAG_SKIP_ANYCAST,
+      /* Reserved         = */ NULL,
+      /* AdapterAddresses = */ pAddrList,
+      /* SizePointer      = */ &dwSize);
+  if (dwStatus != ERROR_SUCCESS)
+    return (0);
+
+  for (pAddrPtr = pAddrList;
+      pAddrPtr != NULL;
+      pAddrPtr = pAddrPtr->Next)
+  {
+    if (strcmp (pszIfName, pAddrPtr->AdapterName) != 0)
+      continue;
+
+    dwIndex = (unsigned) pAddrPtr->IfIndex;
+    break;
+  }
+
+  return (dwIndex);
+} /* }}} unsigned if_nametoindex */
+#endif /* WIN32 */
+
+int lcc_server_set_interface (lcc_server_t *srv, char const *ifname) /* {{{ */
 {
   int if_index;
   int status;
 
-  if ((srv == NULL) || (interface == NULL))
+  if ((srv == NULL) || (ifname == NULL))
     return (EINVAL);
 
-  if_index = if_nametoindex (interface);
+  if_index = if_nametoindex (ifname);
   if (if_index == 0)
     return (ENOENT);
 
@@ -425,7 +475,7 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ *
 #endif
 
       status = setsockopt (srv->fd, IPPROTO_IP, IP_MULTICAST_IF,
-          &mreq, sizeof (mreq));
+          (void *) &mreq, sizeof (mreq));
       if (status != 0)
         return (status);
 
@@ -441,7 +491,7 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ *
     if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr))
     {
       status = setsockopt (srv->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-          &if_index, sizeof (if_index));
+          (void *) &if_index, sizeof (if_index));
       if (status != 0)
         return (status);
 
@@ -452,7 +502,7 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ *
   /* else: Not a multicast interface. */
 #if defined(SO_BINDTODEVICE)
   status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE,
-      interface, strlen (interface) + 1);
+      ifname, strlen (ifname) + 1);
   if (status != 0)
     return (-1);
 #endif