fix #4545: create directory for log file if it does not exist
[oweals/gnunet.git] / src / util / os_network.c
index 3b2254d58ce858614e4aa15b9233c086c207e7b0..5e4546d0877ca95083b54cb8a268be4774084af1 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2004, 2005, 2006, 2015 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 
 */
 
 */
-
 /**
  * @file util/os_network.c
  * @brief function to determine available network interfaces
  * @author Nils Durner
  * @author Heikki Lindholm
  * @author Jake Dust
 /**
  * @file util/os_network.c
  * @brief function to determine available network interfaces
  * @author Nils Durner
  * @author Heikki Lindholm
  * @author Jake Dust
+ * @author LRN
+ * @author Christian Grothoff
  */
  */
-
 #include "platform.h"
 #include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_os_lib.h"
+#include "gnunet_util_lib.h"
+
+
+#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
 
 
+
+#if ! (HAVE_GETIFADDRS && HAVE_FREEIFADDRS)
 /**
 /**
- * @brief Enumerate all network interfaces
+ * Try to enumerate all network interfaces using 'ifconfig'.
  *
  * @param proc the callback function
  *
  * @param proc the callback function
- * @param proc_cls closure for proc
+ * @param proc_cls closure for @a proc
+ * @return #GNUNET_OK if it worked
  */
  */
-void
-GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
-                                   void *proc_cls)
+static int
+try_ifconfig (GNUNET_OS_NetworkInterfaceProcessor proc,
+              void *proc_cls)
 {
 {
-#ifdef MINGW
-  PMIB_IFTABLE pTable;
-  PMIB_IPADDRTABLE pAddrTable;
-  DWORD dwIfIdx, dwExternalNIC;
-  IPAddr theIP;
-
-  /* Determine our external NIC  */
-  theIP = inet_addr ("192.0.34.166");   /* www.example.com */
-  if ((!GNGetBestInterface) ||
-      (GNGetBestInterface (theIP, &dwExternalNIC) != NO_ERROR))
-    {
-      dwExternalNIC = 0;
-    }
-
-  /* Enumerate NICs */
-  EnumNICs (&pTable, &pAddrTable);
-
-  if (pTable)
-    {
-      for (dwIfIdx = 0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++)
-        {
-          char szEntry[1001];
-          DWORD dwIP = 0;
-          int iItm;
-          PIP_ADAPTER_INFO pAdapterInfo;
-          PIP_ADAPTER_INFO pAdapter = NULL;
-          DWORD dwRetVal = 0;
-
-          /* Get IP-Address */
-          int i;
-          for (i = 0; i < pAddrTable->dwNumEntries; i++)
-            {
-              if (pAddrTable->table[i].dwIndex ==
-                  pTable->table[dwIfIdx].dwIndex)
-                {
-                  dwIP = pAddrTable->table[i].dwAddr;
-                  break;
-                }
-            }
-
-          if (dwIP)
-            {
-              BYTE bPhysAddr[MAXLEN_PHYSADDR];
-              char *pszIfName = NULL;
-              char dst[INET_ADDRSTRLEN];
-              struct sockaddr_in sa;
-
-              /* Get friendly interface name */
-              pAdapterInfo =
-                (IP_ADAPTER_INFO *) malloc (sizeof (IP_ADAPTER_INFO));
-              ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
-
-              /* Make an initial call to GetAdaptersInfo to get
-                 the necessary size into the ulOutBufLen variable */
-              if (GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen) ==
-                  ERROR_BUFFER_OVERFLOW)
-                {
-                  free (pAdapterInfo);
-                  pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);
-                }
-
-              if ((dwRetVal =
-                   GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
-                {
-                  pAdapter = pAdapterInfo;
-                  while (pAdapter)
-                    {
-                      if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index)
-                        {
-                          char szKey[251];
-                          long lLen = 250;
-
-                          sprintf (szKey,
-                                   "SYSTEM\\CurrentControlSet\\Control\\Network\\"
-                                   "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
-                                   pAdapter->AdapterName);
-                          pszIfName = (char *) malloc (251);
-                          if (QueryRegistry
-                              (HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName,
-                               &lLen) != ERROR_SUCCESS)
-                            {
-                              free (pszIfName);
-                              pszIfName = NULL;
-                            }
-                        }
-                      pAdapter = pAdapter->Next;
-                    }
-                }
-              free (pAdapterInfo);
-
-              /* Set entry */
-              memset (bPhysAddr, 0, MAXLEN_PHYSADDR);
-              memcpy (bPhysAddr,
-                      pTable->table[dwIfIdx].bPhysAddr,
-                      pTable->table[dwIfIdx].dwPhysAddrLen);
-
-              snprintf (szEntry, 1000, "%s (%s - %I64u)",
-                        pszIfName ? pszIfName : (char *)
-                        pTable->table[dwIfIdx].bDescr, inet_ntop (AF_INET,
-                                                                  &dwIP, dst,
-                                                                  INET_ADDRSTRLEN),
-                        *((unsigned long long *) bPhysAddr));
-              szEntry[1000] = 0;
-
-              if (pszIfName)
-                free (pszIfName);
-
-              sa.sin_family = AF_INET;
-              sa.sin_addr.S_un.S_addr = dwIP;
-
-              if (GNUNET_OK !=
-                  proc (proc_cls,
-                        szEntry,
-                        pAddrTable->table[dwIfIdx].dwIndex == dwExternalNIC,
-                        &sa,
-                        0))
-                break;
-            }
-        }
-      GlobalFree (pAddrTable);
-      GlobalFree (pTable);
-    }
-
-  return GNUNET_YES;
-
-#elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS
-
-  struct ifaddrs *ifa_first;
-  struct ifaddrs *ifa_ptr;
-  socklen_t alen;
-
-  if (getifaddrs (&ifa_first) == 0)
-    {
-      for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next)
-        {
-          if (ifa_ptr->ifa_name != NULL &&
-              ifa_ptr->ifa_addr != NULL && (ifa_ptr->ifa_flags & IFF_UP) != 0)
-            {
-              if ((ifa_ptr->ifa_addr->sa_family != AF_INET) &&
-                  (ifa_ptr->ifa_addr->sa_family != AF_INET6))
-                continue;
-              if (ifa_ptr->ifa_addr->sa_family == AF_INET)
-                alen = sizeof (struct sockaddr_in);
-              else
-                alen = sizeof (struct sockaddr_in6);
-              if (GNUNET_OK != proc (proc_cls,
-                                     ifa_ptr->ifa_name,
-                                     0 == strcmp (ifa_ptr->ifa_name,
-                                                  GNUNET_DEFAULT_INTERFACE),
-                                     ifa_ptr->ifa_addr, alen))
-                break;
-            }
-        }
-      freeifaddrs (ifa_first);
-    }
-#else
+  int i;
   char line[1024];
   char line[1024];
+  char *replace;
   const char *start;
   char ifc[12];
   char addrstr[128];
   const char *start;
   char ifc[12];
   char addrstr[128];
+  char bcstr[128];
+  char netmaskstr[128];
   FILE *f;
   int have_ifc;
   struct sockaddr_in a4;
   struct sockaddr_in6 a6;
   struct in_addr v4;
   struct in6_addr v6;
   FILE *f;
   int have_ifc;
   struct sockaddr_in a4;
   struct sockaddr_in6 a6;
   struct in_addr v4;
   struct in6_addr v6;
+  struct sockaddr_in bcaddr;
+  struct sockaddr_in netmask;
+  struct sockaddr_in6 netmask6;
+  struct sockaddr *pass_bcaddr;
+  struct sockaddr *pass_netmask;
+  int prefixlen;
 
   if (system ("ifconfig -a > /dev/null 2> /dev/null"))
 
   if (system ("ifconfig -a > /dev/null 2> /dev/null"))
-    if (system ("/sbin/ifconfig -a > /dev/null 2> /dev/null") == 0)
+    if (0 == system ("/sbin/ifconfig -a > /dev/null 2> /dev/null"))
       f = popen ("/sbin/ifconfig -a 2> /dev/null", "r");
     else
       f = NULL;
   else
     f = popen ("ifconfig -a 2> /dev/null", "r");
       f = popen ("/sbin/ifconfig -a 2> /dev/null", "r");
     else
       f = NULL;
   else
     f = popen ("ifconfig -a 2> /dev/null", "r");
-  if (!f)
-    {
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
-                                GNUNET_ERROR_TYPE_BULK, "popen", "ifconfig");
-      return;
-    }
+  if (! f)
+  {
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
+                       "popen",
+                       "ifconfig");
+
+    return GNUNET_SYSERR;
+  }
 
   have_ifc = GNUNET_NO;
   ifc[11] = '\0';
   while (NULL != fgets (line, sizeof (line), f))
 
   have_ifc = GNUNET_NO;
   ifc[11] = '\0';
   while (NULL != fgets (line, sizeof (line), f))
+  {
+    if (strlen (line) == 0)
+    {
+      have_ifc = GNUNET_NO;
+      continue;
+    }
+    if (!isspace (line[0]))
+    {
+      have_ifc = (1 == SSCANF (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO;
+      /* would end with ':' on OSX, fix it! */
+      if (ifc[strlen (ifc) - 1] == ':')
+        ifc[strlen (ifc) - 1] = '\0';
+      continue;
+    }
+    if (!have_ifc)
+      continue;                 /* strange input, hope for the best */
+
+    /* make parsing of ipv6 addresses easier */
+    for (replace = line; *replace != '\0'; replace++)
+    {
+      if (*replace == '/')
+        *replace = ' ';
+    }
+    prefixlen = -1;
+
+    start = line;
+    while (('\0' != *start) && (isspace (*start)))
+      start++;
+
+    /* Zero-out stack allocated values */
+    memset (addrstr, 0, 128);
+    memset (netmaskstr, 0, 128);
+    memset (bcstr, 0, 128);
+    prefixlen = 0;
+
+    if ( /* Linux */
+         (3 == SSCANF (start, "inet addr:%127s Bcast:%127s Mask:%127s", addrstr, bcstr, netmaskstr)) ||
+         (2 == SSCANF (start, "inet addr:%127s Mask:%127s", addrstr, netmaskstr)) ||
+         (2 == SSCANF (start, "inet6 addr:%127s %d", addrstr, &prefixlen)) ||
+         /* Solaris, OS X */
+         (1 == SSCANF (start, "inet %127s", addrstr)) ||
+         (1 == SSCANF (start, "inet6 %127s", addrstr)))
     {
     {
-      if (strlen (line) == 0)
+      /* IPv4 */
+      if (1 == inet_pton (AF_INET, addrstr, &v4))
+      {
+        memset (&a4, 0, sizeof (a4));
+        a4.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+        a4.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+        a4.sin_addr = v4;
+
+        pass_bcaddr = NULL;
+        pass_netmask = NULL;
+        if (1 == inet_pton (AF_INET, bcstr, &v4))
         {
         {
-          have_ifc = GNUNET_NO;
-          continue;
+          memset (&bcaddr, 0, sizeof (bcaddr));
+          bcaddr.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+          bcaddr.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+          bcaddr.sin_addr = v4;
+          pass_bcaddr = (struct sockaddr *) &bcaddr;
         }
         }
-      if (!isspace (line[0]))
+        if (1 == inet_pton (AF_INET, netmaskstr, &v4))
         {
         {
-          have_ifc =
-            (1 == SSCANF (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO;
-          /* would end with ':' on OSX, fix it! */
-          if (ifc[strlen (ifc) - 1] == ':')
-            ifc[strlen (ifc) - 1] = '\0';
-          continue;
+          memset (&netmask, 0, sizeof (netmask));
+          netmask.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+          netmask.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+          netmask.sin_addr = v4;
+          pass_netmask = (struct sockaddr *) &netmask;
         }
         }
-      if (!have_ifc)
-        continue;               /* strange input, hope for the best */
-      start = line;
-      while (('\0' != *start) && (isspace (*start)))
-        start++;
-      if (                      /* Linux */
-           (1 == SSCANF (start, "inet addr:%127s", addrstr)) ||
-           (1 == SSCANF (start, "inet6 addr:%127s", addrstr)) ||
-           /* Solaris, OS X */
-           (1 == SSCANF (start, "inet %127s", addrstr)) ||
-           (1 == SSCANF (start, "inet6 %127s", addrstr)))
+
+
+        if (GNUNET_OK !=
+            proc (proc_cls, ifc, 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
+                  (const struct sockaddr *) &a4,
+                  pass_bcaddr, pass_netmask, sizeof (a4)))
+          break;
+        continue;
+      }
+      /* IPv6 */
+      if (1 == inet_pton (AF_INET6, addrstr, &v6))
+      {
+        memset (&a6, 0, sizeof (a6));
+        a6.sin6_family = AF_INET6;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+        a6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
+#endif
+        a6.sin6_addr = v6;
+
+        pass_netmask = NULL;
+        if (prefixlen != -1)
         {
         {
-          /* IPv4 */
-          if (1 == inet_pton (AF_INET, addrstr, &v4))
-            {
-              memset (&a4, 0, sizeof (a4));
-              a4.sin_family = AF_INET;
-              a4.sin_addr = v4;
-              if (GNUNET_OK !=
-                  proc (proc_cls,
-                        ifc,
-                        0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
-                        (const struct sockaddr *) &a4, sizeof (a4)))
-                break;
-              continue;
-            }
-          /* IPv6 */
-          if (1 == inet_pton (AF_INET6, addrstr, &v6))
-            {
-              memset (&a6, 0, sizeof (a6));
-              a6.sin6_family = AF_INET6;
-              a6.sin6_addr = v6;
-              fprintf (stderr, "procing %s\n", addrstr);
-              if (GNUNET_OK !=
-                  proc (proc_cls,
-                        ifc,
-                        0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
-                        (const struct sockaddr *) &a6, sizeof (a6)))
-                break;
-              continue;
-            }
+          memset (v6.s6_addr, 0, sizeof (v6.s6_addr));
+          for (i = 0; i < prefixlen; i++)
+          {
+            v6.s6_addr[i >> 3] |= 1 << (i & 7);
+          }
+          memset (&netmask6, 0, sizeof (netmask6));
+          netmask6.sin6_family = AF_INET6;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+          netmask6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
+#endif
+          netmask6.sin6_addr = v6;
+
+          pass_netmask = (struct sockaddr *) &netmask6;
         }
         }
+
+        if (GNUNET_OK !=
+            proc (proc_cls, ifc, 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
+                  (const struct sockaddr *) &a6,
+                  NULL, pass_netmask, sizeof (a6)))
+          break;
+        continue;
+      }
     }
     }
+  }
   pclose (f);
   pclose (f);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Try to enumerate all network interfaces using 'ip'.
+ *
+ * @param proc the callback function
+ * @param proc_cls closure for @a proc
+ * @return #GNUNET_OK if it worked
+ */
+static int
+try_ip (GNUNET_OS_NetworkInterfaceProcessor proc,
+        void *proc_cls)
+{
+  char line[1024];
+  char *replace;
+  char ifname[64];
+  char afstr[6];
+  char addrstr[128];
+  FILE *f;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  struct in_addr v4;
+  struct in6_addr v6;
+  struct sockaddr_in netmask;
+  struct sockaddr_in6 netmask6;
+  unsigned int i;
+  unsigned int prefixlen;
+
+  f = popen ("ip -o add 2> /dev/null", "r");
+  if (! f)
+  {
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
+                       "popen",
+                       "ip");
+    return GNUNET_SYSERR;
+  }
+
+  while (NULL != fgets (line, sizeof (line), f))
+  {
+    /* make parsing easier */
+    for (replace = line; *replace != '\0'; replace++)
+    {
+      if (*replace == '/')
+        *replace = ' ';
+    }
+    /* Zero-out stack allocated values */
+    memset (ifname, 0, 64);
+    memset (afstr, 0, 6);
+    memset (addrstr, 0, 128);
+    if (4 != SSCANF (line,
+                     "%*u: %63s %5s %127s %6u",
+                     ifname,
+                     afstr,
+                     addrstr,
+                     &prefixlen))
+      continue;
+    /* IPv4 */
+    if ( (0 == strcasecmp ("inet",
+                           afstr)) &&
+         (1 == inet_pton (AF_INET,
+                          addrstr,
+                          &v4)) )
+    {
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      a4.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+      a4.sin_addr = v4;
+
+      memset (&v4.s_addr, 0, sizeof (v4.s_addr));
+      for (i = 0; i < prefixlen; i++)
+        v4.s_addr |= 1 << (i & 7);
+      memset (&netmask, 0, sizeof (netmask));
+      netmask.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      netmask.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+      netmask.sin_addr = v4;
+
+      if (GNUNET_OK !=
+          proc (proc_cls,
+                ifname,
+                (0 == strcmp (ifname,
+                              GNUNET_DEFAULT_INTERFACE)),
+                (const struct sockaddr *) &a4,
+                NULL,
+                (const struct sockaddr *) &netmask,
+                sizeof (a4)))
+        break;
+    }
+    /* IPv6 */
+    if ( (0 == strcasecmp ("inet6",
+                           afstr)) &&
+         (1 == inet_pton (AF_INET6,
+                          addrstr,
+                          &v6)) )
+    {
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      a6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
+#endif
+      a6.sin6_addr = v6;
+
+      memset (v6.s6_addr, 0, sizeof (v6.s6_addr));
+      for (i = 0; i < prefixlen; i++)
+        v6.s6_addr[i >> 3] |= 1 << (i & 7);
+      memset (&netmask6, 0, sizeof (netmask6));
+      netmask6.sin6_family = AF_INET6;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      netmask6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
+#endif
+      netmask6.sin6_addr = v6;
+
+      if (GNUNET_OK !=
+          proc (proc_cls,
+                ifname,
+                (0 == strcmp (ifname,
+                              GNUNET_DEFAULT_INTERFACE)),
+                (const struct sockaddr *) &a6,
+                NULL,
+                (const struct sockaddr *) &netmask6,
+                sizeof (a6)))
+        break;
+    }
+  }
+  pclose (f);
+  return GNUNET_OK;
+}
+#endif
+
+
+/**
+ * @brief Enumerate all network interfaces
+ *
+ * @param proc the callback function
+ * @param proc_cls closure for @a proc
+ */
+void
+GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
+                                   void *proc_cls)
+{
+#ifdef MINGW
+  int r;
+  int i;
+  struct EnumNICs3_results *results = NULL;
+  int results_count;
+
+  r = EnumNICs3 (&results, &results_count);
+  if (r != GNUNET_OK)
+    return;
+
+  for (i = 0; i < results_count; i++)
+  {
+    if (GNUNET_OK !=
+        proc (proc_cls, results[i].pretty_name, results[i].is_default,
+              (const struct sockaddr *) &results[i].address,
+              results[i].
+              flags & ENUMNICS3_BCAST_OK ?
+              (const struct sockaddr *) &results[i].broadcast : NULL,
+              results[i].flags & ENUMNICS3_MASK_OK ?
+              (const struct sockaddr *) &results[i].mask : NULL,
+              results[i].addr_size))
+      break;
+  }
+  EnumNICs3_free (results);
+  return;
+
+#elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS
+
+  struct ifaddrs *ifa_first;
+  struct ifaddrs *ifa_ptr;
+  socklen_t alen;
+
+  if (getifaddrs (&ifa_first) == 0)
+  {
+    for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next)
+    {
+      if (ifa_ptr->ifa_name != NULL && ifa_ptr->ifa_addr != NULL &&
+          (ifa_ptr->ifa_flags & IFF_UP) != 0)
+      {
+        if ((ifa_ptr->ifa_addr->sa_family != AF_INET) &&
+            (ifa_ptr->ifa_addr->sa_family != AF_INET6))
+          continue;
+        if (ifa_ptr->ifa_addr->sa_family == AF_INET)
+          alen = sizeof (struct sockaddr_in);
+        else
+          alen = sizeof (struct sockaddr_in6);
+        if (GNUNET_OK !=
+            proc (proc_cls, ifa_ptr->ifa_name,
+                  0 == strcmp (ifa_ptr->ifa_name, GNUNET_DEFAULT_INTERFACE),
+                  ifa_ptr->ifa_addr, ifa_ptr->ifa_broadaddr,
+                  ifa_ptr->ifa_netmask, alen))
+          break;
+      }
+    }
+    freeifaddrs (ifa_first);
+  }
+#else
+  if (GNUNET_OK ==
+      try_ip (proc,
+              proc_cls))
+    return;
+  if (GNUNET_OK ==
+      try_ifconfig (proc,
+                    proc_cls))
+    return;
+  LOG (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
+       "Failed to enumerate network interfaces\n");
 #endif
 }
 
 #endif
 }