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