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