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.
*/
......
......@@ -100,7 +100,7 @@ DWORD WINAPI AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG N
* PARAMS
* ppIfTable [Out] pointer into which the MIB_IFTABLE is
* allocated and returned.
* bOrder [In] passed to GetIfTable() to order the table
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
......@@ -131,6 +131,18 @@ DWORD WINAPI AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable,
}
static int IpAddrTableSorter(const void *a, const void *b)
{
int ret;
if (a && b)
ret = ((const MIB_IPADDRROW*)a)->dwAddr - ((const MIB_IPADDRROW*)b)->dwAddr;
else
ret = 0;
return ret;
}
/******************************************************************
* AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@)
*
......@@ -140,13 +152,13 @@ DWORD WINAPI AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable,
* PARAMS
* ppIpAddrTable [Out] pointer into which the MIB_IPADDRTABLE is
* allocated and returned.
* bOrder [In] passed to GetIpAddrTable to order the table
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
* RETURNS
* ERROR_INVALID_PARAMETER if ppIpAddrTable is NULL, whatever GetIpAddrTable()
* returns otherwise.
* ERROR_INVALID_PARAMETER if ppIpAddrTable is NULL, other error codes on
* failure, NO_ERROR on success.
*/
DWORD WINAPI AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable,
BOOL bOrder, HANDLE heap, DWORD flags)
......@@ -155,18 +167,35 @@ DWORD WINAPI AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable,
TRACE("ppIpAddrTable %p, bOrder %d, heap %p, flags 0x%08lx\n",
ppIpAddrTable, bOrder, heap, flags);
if (!ppIpAddrTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD dwSize = 0;
ret = getIPAddrTable(ppIpAddrTable, heap, flags);
if (!ret && bOrder)
qsort((*ppIpAddrTable)->table, (*ppIpAddrTable)->dwNumEntries,
sizeof(MIB_IPADDRROW), IpAddrTableSorter);
TRACE("returning %ld\n", ret);
return ret;
}
ret = GetIpAddrTable(*ppIpAddrTable, &dwSize, bOrder);
if (ret == ERROR_INSUFFICIENT_BUFFER) {
*ppIpAddrTable = HeapAlloc(heap, flags, dwSize);
ret = GetIpAddrTable(*ppIpAddrTable, &dwSize, bOrder);
static int IpForwardTableSorter(const void *a, const void *b)
{
int ret;
if (a && b) {
const MIB_IPFORWARDROW* rowA = (const MIB_IPFORWARDROW*)a;
const MIB_IPFORWARDROW* rowB = (const MIB_IPFORWARDROW*)b;
ret = rowA->dwForwardDest - rowB->dwForwardDest;
if (ret == 0) {
ret = rowA->dwForwardProto - rowB->dwForwardProto;
if (ret == 0) {
ret = rowA->dwForwardPolicy - rowB->dwForwardPolicy;
if (ret == 0)
ret = rowA->dwForwardNextHop - rowB->dwForwardNextHop;
}
}
}
TRACE("returning %ld\n", ret);
else
ret = 0;
return ret;
}
......@@ -180,13 +209,13 @@ DWORD WINAPI AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable,
* PARAMS
* ppIpForwardTable [Out] pointer into which the MIB_IPFORWARDTABLE is
* allocated and returned.
* bOrder [In] passed to GetIfTable to order the table
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
* RETURNS
* ERROR_INVALID_PARAMETER if ppIfTable is NULL, whatever
* GetIpForwardTable() returns otherwise.
* ERROR_INVALID_PARAMETER if ppIfTable is NULL, other error codes
* on failure, NO_ERROR on success.
*/
DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *
ppIpForwardTable, BOOL bOrder, HANDLE heap, DWORD flags)
......@@ -195,22 +224,27 @@ DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *
TRACE("ppIpForwardTable %p, bOrder %d, heap %p, flags 0x%08lx\n",
ppIpForwardTable, bOrder, heap, flags);
if (!ppIpForwardTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD dwSize = 0;
ret = GetIpForwardTable(*ppIpForwardTable, &dwSize, bOrder);
if (ret == ERROR_INSUFFICIENT_BUFFER) {
*ppIpForwardTable = HeapAlloc(heap, flags, dwSize);
ret = GetIpForwardTable(*ppIpForwardTable, &dwSize, bOrder);
}
}
ret = getRouteTable(ppIpForwardTable, heap, flags);
if (!ret && bOrder)
qsort((*ppIpForwardTable)->table, (*ppIpForwardTable)->dwNumEntries,
sizeof(MIB_IPFORWARDROW), IpForwardTableSorter);
TRACE("returning %ld\n", ret);
return ret;
}
static int IpNetTableSorter(const void *a, const void *b)
{
int ret;
if (a && b)
ret = ((const MIB_IPNETROW*)a)->dwAddr - ((const MIB_IPNETROW*)b)->dwAddr;
else
ret = 0;
return ret;
}
/******************************************************************
* AllocateAndGetIpNetTableFromStack (IPHLPAPI.@)
*
......@@ -220,13 +254,13 @@ DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *
* PARAMS
* ppIpNetTable [Out] pointer into which the MIB_IPNETTABLE is
* allocated and returned.
* bOrder [In] passed to GetIpNetTable to order the table
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
* RETURNS
* ERROR_INVALID_PARAMETER if ppIpNetTable is NULL, whatever GetIpNetTable()
* returns otherwise.
* ERROR_INVALID_PARAMETER if ppIpNetTable is NULL, other error codes
* on failure, NO_ERROR on success.
*/
DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable,
BOOL bOrder, HANDLE heap, DWORD flags)
......@@ -235,18 +269,35 @@ DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable,
TRACE("ppIpNetTable %p, bOrder %d, heap %p, flags 0x%08lx\n",
ppIpNetTable, bOrder, heap, flags);
if (!ppIpNetTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD dwSize = 0;
ret = getArpTable(ppIpNetTable, heap, flags);
if (!ret && bOrder)
qsort((*ppIpNetTable)->table, (*ppIpNetTable)->dwNumEntries,
sizeof(MIB_IPADDRROW), IpNetTableSorter);
TRACE("returning %ld\n", ret);
return ret;
}
ret = GetIpNetTable(*ppIpNetTable, &dwSize, bOrder);
if (ret == ERROR_INSUFFICIENT_BUFFER) {
*ppIpNetTable = HeapAlloc(heap, flags, dwSize);
ret = GetIpNetTable(*ppIpNetTable, &dwSize, bOrder);
static int TcpTableSorter(const void *a, const void *b)
{
int ret;
if (a && b) {
const MIB_TCPROW* rowA = a;
const MIB_TCPROW* rowB = b;
ret = rowA->dwLocalAddr - rowB->dwLocalAddr;
if (ret == 0) {
ret = rowA->dwLocalPort - rowB->dwLocalPort;
if (ret == 0) {
ret = rowA->dwRemoteAddr - rowB->dwRemoteAddr;
if (ret == 0)
ret = rowA->dwRemotePort - rowB->dwRemotePort;
}
}
}
TRACE("returning %ld\n", ret);
else
ret = 0;
return ret;
}
......@@ -260,7 +311,7 @@ DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable,
* PARAMS
* ppTcpTable [Out] pointer into which the MIB_TCPTABLE is
* allocated and returned.
* bOrder [In] passed to GetTcpTable to order the table
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
......@@ -275,18 +326,29 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable,
TRACE("ppTcpTable %p, bOrder %d, heap %p, flags 0x%08lx\n",
ppTcpTable, bOrder, heap, flags);
if (!ppTcpTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD dwSize = 0;
ret = getTcpTable(ppTcpTable, heap, flags);
if (!ret && bOrder)
qsort((*ppTcpTable)->table, (*ppTcpTable)->dwNumEntries,
sizeof(MIB_TCPROW), TcpTableSorter);
TRACE("returning %ld\n", ret);
return ret;
}
ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder);
if (ret == ERROR_INSUFFICIENT_BUFFER) {
*ppTcpTable = HeapAlloc(heap, flags, dwSize);
ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder);
}
static int UdpTableSorter(const void *a, const void *b)
{
int ret;
if (a && b) {
const MIB_UDPROW* rowA = (const MIB_UDPROW*)a;
const MIB_UDPROW* rowB = (const MIB_UDPROW*)b;
ret = rowA->dwLocalAddr - rowB->dwLocalAddr;
if (ret == 0)
ret = rowA->dwLocalPort - rowB->dwLocalPort;
}
TRACE("returning %ld\n", ret);
else
ret = 0;
return ret;
}
......@@ -300,7 +362,7 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable,
* PARAMS
* ppUdpTable [Out] pointer into which the MIB_UDPTABLE is
* allocated and returned.
* bOrder [In] passed to GetUdpTable to order the table
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
......@@ -315,17 +377,10 @@ DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable,
TRACE("ppUdpTable %p, bOrder %d, heap %p, flags 0x%08lx\n",
ppUdpTable, bOrder, heap, flags);
if (!ppUdpTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD dwSize = 0;
ret = GetUdpTable(*ppUdpTable, &dwSize, bOrder);
if (ret == ERROR_INSUFFICIENT_BUFFER) {
*ppUdpTable = HeapAlloc(heap, flags, dwSize);
ret = GetUdpTable(*ppUdpTable, &dwSize, bOrder);
}
}
ret = getUdpTable(ppUdpTable, heap, flags);
if (!ret && bOrder)
qsort((*ppUdpTable)->table, (*ppUdpTable)->dwNumEntries,
sizeof(MIB_UDPROW), UdpTableSorter);
TRACE("returning %ld\n", ret);
return ret;
}
......@@ -745,7 +800,8 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
DWORD ndx, matchedBits, matchedNdx = 0;
for (ndx = 0, matchedBits = 0; ndx < table->dwNumEntries; ndx++) {
if ((dwDestAddr & table->table[ndx].dwForwardMask) ==
if (table->table[ndx].dwForwardType != MIB_IPROUTE_TYPE_INVALID &&
(dwDestAddr & table->table[ndx].dwForwardMask) ==
(table->table[ndx].dwForwardDest & table->table[ndx].dwForwardMask)) {
DWORD numShifts, mask;
......@@ -758,9 +814,15 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
}
}
}
memcpy(pBestRoute, &table->table[matchedNdx], sizeof(MIB_IPFORWARDROW));
if (matchedNdx < table->dwNumEntries) {
memcpy(pBestRoute, &table->table[matchedNdx], sizeof(MIB_IPFORWARDROW));
ret = ERROR_SUCCESS;
}
else {
/* No route matches, which can happen if there's no default route. */
ret = ERROR_HOST_UNREACHABLE;
}
HeapFree(GetProcessHeap(), 0, table);
ret = ERROR_SUCCESS;
}
else
ret = ERROR_OUTOFMEMORY;
......@@ -911,6 +973,7 @@ DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
else {
DWORD ndx;
*pdwSize = size;
pIfTable->dwNumEntries = 0;
for (ndx = 0; ndx < table->numIndexes; ndx++) {
pIfTable->table[ndx].dwIndex = table->indexes[ndx];
......@@ -1003,18 +1066,6 @@ DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
}
static int IpAddrTableSorter(const void *a, const void *b)
{
int ret;
if (a && b)
ret = ((const MIB_IPADDRROW*)a)->dwAddr - ((const MIB_IPADDRROW*)b)->dwAddr;
else
ret = 0;
return ret;
}
/******************************************************************
* GetIpAddrTable (IPHLPAPI.@)
*
......@@ -1045,83 +1096,31 @@ DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL
if (!pdwSize)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numInterfaces = getNumInterfaces();
ULONG size = sizeof(MIB_IPADDRTABLE) + (numInterfaces - 1) *
sizeof(MIB_IPADDRROW);
if (!pIpAddrTable || *pdwSize < size) {
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
InterfaceIndexTable *table = getInterfaceIndexTable();
PMIB_IPADDRTABLE table;
if (table) {
size = sizeof(MIB_IPADDRTABLE) + (table->numIndexes - 1) *
sizeof(MIB_IPADDRROW);
if (*pdwSize < size) {
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
DWORD ndx, bcast;
ret = getIPAddrTable(&table, GetProcessHeap(), 0);
if (ret == NO_ERROR)
{
ULONG size = sizeof(MIB_IPADDRTABLE) + (table->dwNumEntries - 1) *
sizeof(MIB_IPADDRROW);
pIpAddrTable->dwNumEntries = 0;
for (ndx = 0; ndx < table->numIndexes; ndx++) {
pIpAddrTable->table[ndx].dwIndex = table->indexes[ndx];
pIpAddrTable->table[ndx].dwAddr =
getInterfaceIPAddrByIndex(table->indexes[ndx]);
pIpAddrTable->table[ndx].dwMask =
getInterfaceMaskByIndex(table->indexes[ndx]);
/* 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(table->indexes[ndx]);
pIpAddrTable->table[ndx].dwBCastAddr =
(bcast & pIpAddrTable->table[ndx].dwMask) ? 1 : 0;
/* FIXME: hardcoded reasm size, not sure where to get it */
pIpAddrTable->table[ndx].dwReasmSize = 65535;
pIpAddrTable->table[ndx].unused1 = 0;
pIpAddrTable->table[ndx].wType = 0; /* aka unused2 */
pIpAddrTable->dwNumEntries++;
}
if (bOrder)
qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries,
sizeof(MIB_IPADDRROW), IpAddrTableSorter);
ret = NO_ERROR;
}
HeapFree(GetProcessHeap(), 0, table);
if (!pIpAddrTable || *pdwSize < size) {
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else
ret = ERROR_OUTOFMEMORY;
}
}
TRACE("returning %ld\n", ret);
return ret;
}
static int IpForwardTableSorter(const void *a, const void *b)
{
int ret;
if (a && b) {
const MIB_IPFORWARDROW* rowA = (const MIB_IPFORWARDROW*)a;
const MIB_IPFORWARDROW* rowB = (const MIB_IPFORWARDROW*)b;
ret = rowA->dwForwardDest - rowB->dwForwardDest;
if (ret == 0) {
ret = rowA->dwForwardProto - rowB->dwForwardProto;
if (ret == 0) {
ret = rowA->dwForwardPolicy - rowB->dwForwardPolicy;
if (ret == 0)
ret = rowA->dwForwardNextHop - rowB->dwForwardNextHop;
else {
*pdwSize = size;
memcpy(pIpAddrTable, table, sizeof(MIB_IPADDRTABLE) +
(table->dwNumEntries - 1) * sizeof(MIB_IPADDRROW));
if (bOrder)
qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries,
sizeof(MIB_IPADDRROW), IpAddrTableSorter);
ret = NO_ERROR;
}
HeapFree(GetProcessHeap(), 0, table);
}
}
else
ret = 0;
TRACE("returning %ld\n", ret);
return ret;
}
......@@ -1165,45 +1164,19 @@ DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSi
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
RouteTable *table = getRouteTable();
if (table) {
sizeNeeded = sizeof(MIB_IPFORWARDTABLE) + (table->numRoutes - 1) *
PMIB_IPFORWARDTABLE table;
ret = getRouteTable(&table, GetProcessHeap(), 0);
if (!ret) {
sizeNeeded = sizeof(MIB_IPFORWARDTABLE) + (table->dwNumEntries - 1) *
sizeof(MIB_IPFORWARDROW);
if (*pdwSize < sizeNeeded) {
*pdwSize = sizeNeeded;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
DWORD ndx;
pIpForwardTable->dwNumEntries = table->numRoutes;
for (ndx = 0; ndx < numRoutes; ndx++) {
pIpForwardTable->table[ndx].dwForwardIfIndex =
table->routes[ndx].ifIndex;
pIpForwardTable->table[ndx].dwForwardDest =
table->routes[ndx].dest;
pIpForwardTable->table[ndx].dwForwardMask =
table->routes[ndx].mask;
pIpForwardTable->table[ndx].dwForwardPolicy = 0;
pIpForwardTable->table[ndx].dwForwardNextHop =
table->routes[ndx].gateway;
/* FIXME: this type is appropriate for local interfaces; may not
always be appropriate */
pIpForwardTable->table[ndx].dwForwardType = MIB_IPROUTE_TYPE_DIRECT;
/* FIXME: other protos might be appropriate, e.g. the default route
is typically set with MIB_IPPROTO_NETMGMT instead */
pIpForwardTable->table[ndx].dwForwardProto = MIB_IPPROTO_LOCAL;
/* punt on age and AS */
pIpForwardTable->table[ndx].dwForwardAge = 0;
pIpForwardTable->table[ndx].dwForwardNextHopAS = 0;
pIpForwardTable->table[ndx].dwForwardMetric1 =
table->routes[ndx].metric;
/* rest of the metrics are 0.. */
pIpForwardTable->table[ndx].dwForwardMetric2 = 0;
pIpForwardTable->table[ndx].dwForwardMetric3 = 0;
pIpForwardTable->table[ndx].dwForwardMetric4 = 0;
pIpForwardTable->table[ndx].dwForwardMetric5 = 0;
}
*pdwSize = sizeNeeded;
memcpy(pIpForwardTable, table, sizeNeeded);
if (bOrder)
qsort(pIpForwardTable->table, pIpForwardTable->dwNumEntries,
sizeof(MIB_IPFORWARDROW), IpForwardTableSorter);
......@@ -1211,8 +1184,6 @@ DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSi
}
HeapFree(GetProcessHeap(), 0, table);
}
else
ret = ERROR_OUTOFMEMORY;
}
}
TRACE("returning %ld\n", ret);
......@@ -1220,18 +1191,6 @@ DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSi
}
static int IpNetTableSorter(const void *a, const void *b)
{
int ret;
if (a && b)
ret = ((const MIB_IPNETROW*)a)->dwAddr - ((const MIB_IPNETROW*)b)->dwAddr;
else
ret = 0;
return ret;
}
/******************************************************************
* GetIpNetTable (IPHLPAPI.@)
*
......@@ -1270,9 +1229,10 @@ DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOr
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
PMIB_IPNETTABLE table = getArpTable();
PMIB_IPNETTABLE table;
if (table) {
ret = getArpTable(&table, GetProcessHeap(), 0);
if (!ret) {
size = sizeof(MIB_IPNETTABLE) + (table->dwNumEntries - 1) *
sizeof(MIB_IPNETROW);
if (*pdwSize < size) {
......@@ -1280,6 +1240,7 @@ DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOr
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
*pdwSize = size;
memcpy(pIpNetTable, table, size);
if (bOrder)
qsort(pIpNetTable->table, pIpNetTable->dwNumEntries,
......@@ -1288,8 +1249,6 @@ DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOr
}
HeapFree(GetProcessHeap(), 0, table);
}
else
ret = ERROR_OUTOFMEMORY;
}
}
TRACE("returning %ld\n", ret);
......@@ -1502,30 +1461,6 @@ DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats)
}
static int TcpTableSorter(const void *a, const void *b)
{
int ret;
if (a && b) {
const MIB_TCPROW* rowA = a;
const MIB_TCPROW* rowB = b;
ret = rowA->dwLocalAddr - rowB->dwLocalAddr;
if (ret == 0) {
ret = rowA->dwLocalPort - rowB->dwLocalPort;
if (ret == 0) {
ret = rowA->dwRemoteAddr - rowB->dwRemoteAddr;
if (ret == 0)
ret = rowA->dwRemotePort - rowB->dwRemotePort;
}
}
}
else
ret = 0;
return ret;
}
/******************************************************************
* GetTcpTable (IPHLPAPI.@)
*
......@@ -1558,16 +1493,17 @@ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numEntries = getNumTcpEntries();
ULONG size = sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW);
DWORD size = sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW);
if (!pTcpTable || *pdwSize < size) {
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
PMIB_TCPTABLE table = getTcpTable();
PMIB_TCPTABLE table;
if (table) {
ret = getTcpTable(&table, GetProcessHeap(), 0);
if (!ret) {
size = sizeof(MIB_TCPTABLE) + (table->dwNumEntries - 1) *
sizeof(MIB_TCPROW);
if (*pdwSize < size) {
......@@ -1575,6 +1511,7 @@ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder)
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
*pdwSize = size;
memcpy(pTcpTable, table, size);
if (bOrder)
qsort(pTcpTable->table, pTcpTable->dwNumEntries,
......@@ -1615,24 +1552,6 @@ DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats)
}
static int UdpTableSorter(const void *a, const void *b)
{
int ret;
if (a && b) {
const MIB_UDPROW* rowA = (const MIB_UDPROW*)a;
const MIB_UDPROW* rowB = (const MIB_UDPROW*)b;
ret = rowA->dwLocalAddr - rowB->dwLocalAddr;
if (ret == 0)
ret = rowA->dwLocalPort - rowB->dwLocalPort;
}
else
ret = 0;
return ret;
}
/******************************************************************
* GetUdpTable (IPHLPAPI.@)
*
......@@ -1664,16 +1583,17 @@ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numEntries = getNumUdpEntries();
ULONG size = sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW);
DWORD size = sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW);
if (!pUdpTable || *pdwSize < size) {
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
PMIB_UDPTABLE table = getUdpTable();
PMIB_UDPTABLE table;
if (table) {
ret = getUdpTable(&table, GetProcessHeap(), 0);
if (!ret) {
size = sizeof(MIB_UDPTABLE) + (table->dwNumEntries - 1) *
sizeof(MIB_UDPROW);
if (*pdwSize < size) {
......@@ -1681,6 +1601,7 @@ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
*pdwSize = size;
memcpy(pUdpTable, table, size);
if (bOrder)
qsort(pUdpTable->table, pUdpTable->dwNumEntries,
......@@ -1832,7 +1753,7 @@ DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped)
* Send an ARP request.
*
* PARAMS
* DestIP [In] attemp to obtain this IP
* DestIP [In] attempt to obtain this IP
* SrcIP [In] optional sender IP address
* pMacAddr [Out] buffer for the mac address
* PhyAddrLen [In/Out] length of the output buffer
......
......@@ -38,6 +38,9 @@
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif
......@@ -561,70 +564,101 @@ DWORD getNumRoutes(void)
return getNumWithOneHeader("/proc/net/route");
}
RouteTable *getRouteTable(void)
DWORD getRouteTable(PMIB_IPFORWARDTABLE *ppIpForwardTable, HANDLE heap,
DWORD flags)
{
DWORD numRoutes = getNumRoutes();
RouteTable *ret;
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(RouteTable) + (numRoutes - 1) * sizeof(RouteEntry));
if (ret) {
FILE *fp;
/* get from /proc/net/route, no error if can't */
fp = fopen("/proc/net/route", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->numRoutes < numRoutes) {
DWORD ret;
if (!ppIpForwardTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numRoutes = getNumRoutes();
PMIB_IPFORWARDTABLE table = HeapAlloc(heap, flags,
sizeof(MIB_IPFORWARDTABLE) + (numRoutes - 1) * sizeof(MIB_IPFORWARDROW));
if (table) {
FILE *fp;
ret = NO_ERROR;
*ppIpForwardTable = table;
table->dwNumEntries = 0;
/* get from /proc/net/route, no error if can't */
fp = fopen("/proc/net/route", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
DWORD index;
while (!isspace(*ptr))
while (ptr && table->dwNumEntries < numRoutes) {
memset(&table->table[table->dwNumEntries], 0,
sizeof(MIB_IPFORWARDROW));
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
DWORD index;
while (!isspace(*ptr))
ptr++;
*ptr = '\0';
ptr++;
*ptr = '\0';
ptr++;
if (getInterfaceIndexByName(buf, &index) == NO_ERROR) {
char *endPtr;
ret->routes[ret->numRoutes].ifIndex = index;
if (*ptr) {
ret->routes[ret->numRoutes].dest = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
ret->routes[ret->numRoutes].gateway = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* flags, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* refcount, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* use, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
ret->routes[ret->numRoutes].metric = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
if (getInterfaceIndexByName(buf, &index) == NO_ERROR) {
char *endPtr;
table->table[table->dwNumEntries].dwForwardIfIndex = index;
if (*ptr) {
table->table[table->dwNumEntries].dwForwardDest =
strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
table->table[table->dwNumEntries].dwForwardNextHop =
strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
DWORD flags = strtoul(ptr, &endPtr, 16);
if (!(flags & RTF_UP))
table->table[table->dwNumEntries].dwForwardType =
MIB_IPROUTE_TYPE_INVALID;
else if (flags & RTF_GATEWAY)
table->table[table->dwNumEntries].dwForwardType =
MIB_IPROUTE_TYPE_INDIRECT;
else
table->table[table->dwNumEntries].dwForwardType =
MIB_IPROUTE_TYPE_DIRECT;
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* refcount, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* use, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
table->table[table->dwNumEntries].dwForwardMetric1 =
strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
table->table[table->dwNumEntries].dwForwardMask =
strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
/* FIXME: other protos might be appropriate, e.g. the default
* route is typically set with MIB_IPPROTO_NETMGMT instead */
table->table[table->dwNumEntries].dwForwardProto =
MIB_IPPROTO_LOCAL;
table->dwNumEntries++;
}
if (ptr && *ptr) {
ret->routes[ret->numRoutes].mask = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
ret->numRoutes++;
}
}
fclose(fp);
}
fclose(fp);
}
else
ret = ERROR_OUTOFMEMORY;
}
return ret;
}
......@@ -634,75 +668,90 @@ DWORD getNumArpEntries(void)
return getNumWithOneHeader("/proc/net/arp");
}
PMIB_IPNETTABLE getArpTable(void)
DWORD getArpTable(PMIB_IPNETTABLE *ppIpNetTable, HANDLE heap, DWORD flags)
{
DWORD numEntries = getNumArpEntries();
PMIB_IPNETTABLE ret;
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(MIB_IPNETTABLE) + (numEntries - 1) * sizeof(MIB_IPNETROW));
if (ret) {
FILE *fp;
/* get from /proc/net/arp, no error if can't */
fp = fopen("/proc/net/arp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
DWORD ret;
if (!ppIpNetTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numEntries = getNumArpEntries();
PMIB_IPNETTABLE table = HeapAlloc(heap, flags,
sizeof(MIB_IPNETTABLE) + (numEntries - 1) * sizeof(MIB_IPNETROW));
if (table) {
FILE *fp;
ret = NO_ERROR;
*ppIpNetTable = table;
table->dwNumEntries = 0;
/* get from /proc/net/arp, no error if can't */
fp = fopen("/proc/net/arp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
while (ptr && table->dwNumEntries < numEntries) {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
ret->table[ret->dwNumEntries].dwAddr = inet_addr(ptr);
while (ptr && *ptr && !isspace(*ptr))
ptr++;
memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_IPNETROW));
table->table[table->dwNumEntries].dwAddr = inet_addr(ptr);
while (ptr && *ptr && !isspace(*ptr))
ptr++;
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* hw type (skip) */
ptr = endPtr;
}
if (ptr && *ptr) {
DWORD flags = strtoul(ptr, &endPtr, 16);
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* hw type (skip) */
ptr = endPtr;
}
if (ptr && *ptr) {
DWORD flags = strtoul(ptr, &endPtr, 16);
#ifdef ATF_COM
if (flags & ATF_COM)
ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_DYNAMIC;
else
if (flags & ATF_COM)
table->table[table->dwNumEntries].dwType =
MIB_IPNET_TYPE_DYNAMIC;
else
#endif
#ifdef ATF_PERM
if (flags & ATF_PERM)
ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_STATIC;
else
if (flags & ATF_PERM)
table->table[table->dwNumEntries].dwType =
MIB_IPNET_TYPE_STATIC;
else
#endif
ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_OTHER;
ptr = endPtr;
}
while (ptr && *ptr && isspace(*ptr))
ptr++;
while (ptr && *ptr && !isspace(*ptr)) {
DWORD byte = strtoul(ptr, &endPtr, 16);
table->table[table->dwNumEntries].dwType = MIB_IPNET_TYPE_OTHER;
if (endPtr && *endPtr) {
endPtr++;
ret->table[ret->dwNumEntries].bPhysAddr[
ret->table[ret->dwNumEntries].dwPhysAddrLen++] = byte & 0x0ff;
ptr = endPtr;
}
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* mask (skip) */
ptr = endPtr;
while (ptr && *ptr && isspace(*ptr))
ptr++;
while (ptr && *ptr && !isspace(*ptr)) {
DWORD byte = strtoul(ptr, &endPtr, 16);
if (endPtr && *endPtr) {
endPtr++;
table->table[table->dwNumEntries].bPhysAddr[
table->table[table->dwNumEntries].dwPhysAddrLen++] =
byte & 0x0ff;
}
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* mask (skip) */
ptr = endPtr;
}
getInterfaceIndexByName(ptr,
&table->table[table->dwNumEntries].dwIndex);
table->dwNumEntries++;
}
getInterfaceIndexByName(ptr, &ret->table[ret->dwNumEntries].dwIndex);
ret->dwNumEntries++;
}
fclose(fp);
}
fclose(fp);
}
else
ret = ERROR_OUTOFMEMORY;
}
return ret;
}
......@@ -712,49 +761,60 @@ DWORD getNumUdpEntries(void)
return getNumWithOneHeader("/proc/net/udp");
}
PMIB_UDPTABLE getUdpTable(void)
DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTable, HANDLE heap, DWORD flags)
{
DWORD numEntries = getNumUdpEntries();
PMIB_UDPTABLE ret;
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW));
if (ret) {
FILE *fp;
/* get from /proc/net/udp, no error if can't */
fp = fopen("/proc/net/udp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
DWORD ret;
if (!ppUdpTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numEntries = getNumUdpEntries();
PMIB_UDPTABLE table = HeapAlloc(heap, flags,
sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW));
if (table) {
FILE *fp;
ret = NO_ERROR;
*ppUdpTable = table;
table->dwNumEntries = 0;
/* get from /proc/net/udp, no error if can't */
fp = fopen("/proc/net/udp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
while (ptr && table->dwNumEntries < numEntries) {
memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_UDPROW));
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
table->table[table->dwNumEntries].dwLocalAddr = strtoul(ptr,
&endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
table->table[table->dwNumEntries].dwLocalPort = strtoul(ptr,
&endPtr, 16);
ptr = endPtr;
}
table->dwNumEntries++;
}
ret->dwNumEntries++;
}
fclose(fp);
}
fclose(fp);
}
else
ret = ERROR_OUTOFMEMORY;
}
return ret;
}
......@@ -764,101 +824,122 @@ DWORD getNumTcpEntries(void)
return getNumWithOneHeader("/proc/net/tcp");
}
PMIB_TCPTABLE getTcpTable(void)
DWORD getTcpTable(PMIB_TCPTABLE *ppTcpTable, HANDLE heap, DWORD flags)
{
DWORD numEntries = getNumTcpEntries();
PMIB_TCPTABLE ret;
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW));
if (ret) {
FILE *fp;
/* get from /proc/net/tcp, no error if can't */
fp = fopen("/proc/net/tcp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
DWORD ret;
if (!ppTcpTable)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numEntries = getNumTcpEntries();
PMIB_TCPTABLE table = HeapAlloc(heap, flags,
sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW));
if (table) {
FILE *fp;
ret = NO_ERROR;
*ppTcpTable = table;
table->dwNumEntries = 0;
/* get from /proc/net/tcp, no error if can't */
fp = fopen("/proc/net/tcp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
while (ptr && table->dwNumEntries < numEntries) {
memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_TCPROW));
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
while (ptr && *ptr && *ptr != ':')
ptr++;
if (ptr && *ptr)
ptr++;
if (ptr && *ptr) {
ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ret->table[ret->dwNumEntries].dwRemoteAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwRemotePort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
DWORD state = strtoul(ptr, &endPtr, 16);
switch (state)
{
case TCPS_ESTABLISHED:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_ESTAB;
break;
case TCPS_SYN_SENT:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_SYN_SENT;
break;
case TCPS_SYN_RECEIVED:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_SYN_RCVD;
break;
case TCPS_FIN_WAIT_1:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_FIN_WAIT1;
break;
case TCPS_FIN_WAIT_2:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_FIN_WAIT2;
break;
case TCPS_TIME_WAIT:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_TIME_WAIT;
break;
case TCPS_CLOSED:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_CLOSED;
break;
case TCPS_CLOSE_WAIT:
ret->table[ret->dwNumEntries].dwState =
MIB_TCP_STATE_CLOSE_WAIT;
break;
case TCPS_LAST_ACK:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_LAST_ACK;
break;
case TCPS_LISTEN:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_LISTEN;
break;
case TCPS_CLOSING:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_CLOSING;
break;
while (ptr && *ptr && *ptr != ':')
ptr++;
if (ptr && *ptr)
ptr++;
if (ptr && *ptr) {
table->table[table->dwNumEntries].dwLocalAddr = strtoul(ptr,
&endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
table->table[table->dwNumEntries].dwLocalPort = strtoul(ptr,
&endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
table->table[table->dwNumEntries].dwRemoteAddr = strtoul(ptr,
&endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
table->table[table->dwNumEntries].dwRemotePort = strtoul(ptr,
&endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
DWORD state = strtoul(ptr, &endPtr, 16);
switch (state)
{
case TCPS_ESTABLISHED:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_ESTAB;
break;
case TCPS_SYN_SENT:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_SYN_SENT;
break;
case TCPS_SYN_RECEIVED:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_SYN_RCVD;
break;
case TCPS_FIN_WAIT_1:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_FIN_WAIT1;
break;
case TCPS_FIN_WAIT_2:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_FIN_WAIT2;
break;
case TCPS_TIME_WAIT:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_TIME_WAIT;
break;
case TCPS_CLOSED:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_CLOSED;
break;
case TCPS_CLOSE_WAIT:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_CLOSE_WAIT;
break;
case TCPS_LAST_ACK:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_LAST_ACK;
break;
case TCPS_LISTEN:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_LISTEN;
break;
case TCPS_CLOSING:
table->table[table->dwNumEntries].dwState =
MIB_TCP_STATE_CLOSING;
break;
}
ptr = endPtr;
}
ptr = endPtr;
table->dwNumEntries++;
}
ret->dwNumEntries++;
}
fclose(fp);
}
fclose(fp);
}
else
ret = ERROR_OUTOFMEMORY;
}
return ret;
}
......@@ -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