Juan Lang wrote:

+/* Enumerates the IP addresses in the system using SIOCGIFCONF, returning
+ * the count to you in *pcAddresses.  It also returns to you the struct ifconf
+ * used by the call to ioctl, so that you may process the addresses further.
+ * Free ifc->ifc_buf using HeapFree.
+ * Returns NO_ERROR on success, something else on failure.
+ */
+static DWORD enumIPAddresses(PDWORD pcAddresses, struct ifconf *ifc)
+{
+  DWORD ret;
+  int fd;
+
+  fd = socket(PF_INET, SOCK_DGRAM, 0);
+  if (fd != -1) {
+    int ioctlRet = 0;
+    DWORD guessedNumAddresses = 0, numAddresses = 0;
+    caddr_t ifPtr;
+
+    ret = NO_ERROR;
+    ifc->ifc_len = 0;
+    ifc->ifc_buf = NULL;
+    /* there is no way to know the interface count beforehand,
+       so we need to loop again and again upping our max each time
+       until returned < max */
+    do {
+      HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
+      if (guessedNumAddresses == 0)
+        guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
+      else
+        guessedNumAddresses *= 2;
+      ifc->ifc_len = sizeof(struct ifreq) * guessedNumAddresses;
+      ifc->ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc->ifc_len);
+      ioctlRet = ioctl(fd, SIOCGIFCONF, ifc);
+    } while (ioctlRet == 0 &&
+     ifc->ifc_len == (sizeof(struct ifreq) * guessedNumAddresses));
+
+    if (ioctlRet == 0) {
+      ifPtr = ifc->ifc_buf;
+      while (ifPtr && ifPtr < ifc->ifc_buf + ifc->ifc_len) {
+        numAddresses++;
+        ifPtr += ifreq_len((struct ifreq *)ifPtr);
+      }
+    }
+    else
+      ret = ERROR_INVALID_PARAMETER; /* FIXME: map from errno to Win32 */
+    if (!ret)
+      *pcAddresses = numAddresses;
+    else
+    {
+      HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
+      ifc->ifc_buf = NULL;
+    }
+  }
+  else
+    ret = ERROR_NO_SYSTEM_RESOURCES;
+  return ret;
+}
+

You leak an fd in this function.

--
Rob Shearman



Reply via email to