iphlpapi: Clean up memory allocation.
- pass heap to allocate from directly to helper functions, instead of
unnecessarily copying returned data
- use public types rather than internal ones
- make sure GetBestRoute doesn't return bogus matches
diff --git a/dlls/iphlpapi/ifenum.c b/dlls/iphlpapi/ifenum.c
index e794d09..0283d36 100644
--- a/dlls/iphlpapi/ifenum.c
+++ b/dlls/iphlpapi/ifenum.c
@@ -927,6 +927,96 @@
return ERROR_INVALID_DATA;
}
+DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
+{
+ DWORD ret;
+
+ if (!ppIpAddrTable)
+ ret = ERROR_INVALID_PARAMETER;
+ else
+ {
+ int fd;
+
+ fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (fd != -1) {
+ int ioctlRet;
+ DWORD guessedNumAddresses, numAddresses;
+ struct ifconf ifc;
+ caddr_t ifPtr;
+
+ guessedNumAddresses = 0;
+ ioctlRet = 0;
+ memset(&ifc, 0, sizeof(ifc));
+ /* 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 {
+ if (guessedNumAddresses == 0)
+ guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
+ else
+ guessedNumAddresses *= 2;
+ HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
+ 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) {
+ numAddresses = 0;
+ ifPtr = ifc.ifc_buf;
+ while (ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
+ numAddresses++;
+ ifPtr += ifreq_len((struct ifreq *)ifPtr);
+ }
+ *ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) +
+ (numAddresses - 1) * sizeof(MIB_IPADDRROW));
+ if (*ppIpAddrTable) {
+ DWORD i = 0, bcast;
+
+ ret = NO_ERROR;
+ (*ppIpAddrTable)->dwNumEntries = numAddresses;
+ ifPtr = ifc.ifc_buf;
+ while (!ret && ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
+ struct ifreq *ifr = (struct ifreq *)ifPtr;
+
+ ret = getInterfaceIndexByName(ifr->ifr_name,
+ &(*ppIpAddrTable)->table[i].dwIndex);
+ (*ppIpAddrTable)->table[i].dwAddr =
+ getInterfaceIPAddrByIndex((*ppIpAddrTable)->table[i].dwIndex);
+ (*ppIpAddrTable)->table[i].dwMask =
+ getInterfaceMaskByIndex((*ppIpAddrTable)->table[i].dwIndex);
+ /* the dwBCastAddr member isn't the broadcast address, it indicates
+ * whether the interface uses the 1's broadcast address (1) or the
+ * 0's broadcast address (0).
+ */
+ bcast = getInterfaceBCastAddrByIndex(
+ (*ppIpAddrTable)->table[i].dwIndex);
+ (*ppIpAddrTable)->table[i].dwBCastAddr =
+ (bcast & (*ppIpAddrTable)->table[i].dwMask) ? 1 : 0;
+ /* FIXME: hardcoded reasm size, not sure where to get it */
+ (*ppIpAddrTable)->table[i].dwReasmSize = 65535;
+
+ (*ppIpAddrTable)->table[i].unused1 = 0;
+ (*ppIpAddrTable)->table[i].wType = 0;
+ ifPtr += ifreq_len(ifr);
+ i++;
+ }
+ }
+ else
+ ret = ERROR_OUTOFMEMORY;
+ }
+ else
+ ret = ERROR_INVALID_PARAMETER;
+ HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
+ close(fd);
+ }
+ else
+ ret = ERROR_NO_SYSTEM_RESOURCES;
+ }
+ return ret;
+}
+
char *toIPAddressString(unsigned int addr, char string[16])
{
if (string) {