Commit 5cd6b342 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

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
parent 2d4edc3b
......@@ -927,6 +927,96 @@ DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
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) {
......
......@@ -125,6 +125,13 @@ DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu);
DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry);
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry);
/* Gets the configured IP addresses for the system, and sets *ppIpAddrTable to
* a table of them allocated from heap, or NULL if out of memory. Returns
* NO_ERROR on success, something else on failure. Note there may be more than
* one IP address may exist per interface.
*/
DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags);
/* Converts the network-order bytes in addr to a printable string. Returns
* string.
*/
......
......@@ -15,9 +15,8 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This module implements functions shared by DLLs that need to get network-
* related statistics. It's meant to hide some platform-specificisms, and
* share code that was previously duplicated.
* This module implements functions that get network-related statistics.
* It's meant to hide some platform-specificisms.
*/
#ifndef WINE_IPSTATS_H_
#define WINE_IPSTATS_H_
......@@ -53,53 +52,37 @@ DWORD getTCPStats(MIB_TCPSTATS *stats);
*/
DWORD getUDPStats(MIB_UDPSTATS *stats);
/* Route table functions */
/* Returns the number of entries in the route table. */
DWORD getNumRoutes(void);
/* Minimalist route entry, only has the fields I can actually fill in. How
* these map to the different windows route data structures is up to you.
*/
typedef struct _RouteEntry {
DWORD dest;
DWORD mask;
DWORD gateway;
DWORD ifIndex;
DWORD metric;
} RouteEntry;
typedef struct _RouteTable {
DWORD numRoutes;
RouteEntry routes[1];
} RouteTable;
/* Allocates and returns to you the route table, or NULL if it can't allocate
* enough memory. HeapFree() the returned table.
/* Allocates the route table from heap and returns it to you in
* *ppIpForwardTable. Returns NO_ERROR on success, something else on failure.
*/
RouteTable *getRouteTable(void);
DWORD getRouteTable(PMIB_IPFORWARDTABLE *ppIpForwardTable, HANDLE heap,
DWORD flags);
/* Returns the number of entries in the arp table. */
DWORD getNumArpEntries(void);
/* Allocates and returns to you the arp table, or NULL if it can't allocate
* enough memory. HeapFree() the returned table.
/* Allocates the arp table from heap and returns it to you in *ppIpNetTable.
* Returns NO_ERROR on success, something else on failure.
*/
PMIB_IPNETTABLE getArpTable(void);
DWORD getArpTable(PMIB_IPNETTABLE *ppIpNetTable, HANDLE heap, DWORD flags);
/* Returns the number of entries in the UDP state table. */
DWORD getNumUdpEntries(void);
/* Allocates and returns to you the UDP state table, or NULL if it can't
* allocate enough memory. HeapFree() the returned table.
/* Allocates the UDP state table from heap and returns it to you in *ppUdpTable.
* Returns NO_ERROR on success, something else on failure.
*/
PMIB_UDPTABLE getUdpTable(void);
DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTable, HANDLE heap, DWORD flags);
/* Returns the number of entries in the TCP state table. */
DWORD getNumTcpEntries(void);
/* Allocates and returns to you the TCP state table, or NULL if it can't
* allocate enough memory. HeapFree() the returned table.
/* Allocates the TCP state table from heap and returns it to you in *ppTcpTable.
* Returns NO_ERROR on success, something else on failure.
*/
PMIB_TCPTABLE getTcpTable(void);
DWORD getTcpTable(PMIB_TCPTABLE *ppTcpTable, HANDLE heap, DWORD flags);
#endif /* ndef WINE_IPSTATS_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment