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
This commit is contained in:
parent
2d4edc3b3d
commit
5cd6b34259
|
@ -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,22 +326,33 @@ 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, &dwSize, bOrder);
|
||||
if (ret == ERROR_INSUFFICIENT_BUFFER) {
|
||||
*ppTcpTable = HeapAlloc(heap, flags, dwSize);
|
||||
ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder);
|
||||
}
|
||||
}
|
||||
ret = getTcpTable(ppTcpTable, heap, flags);
|
||||
if (!ret && bOrder)
|
||||
qsort((*ppTcpTable)->table, (*ppTcpTable)->dwNumEntries,
|
||||
sizeof(MIB_TCPROW), TcpTableSorter);
|
||||
TRACE("returning %ld\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* AllocateAndGetUdpTableFromStack (IPHLPAPI.@)
|
||||
*
|
||||
|
@ -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,56 +1096,28 @@ 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);
|
||||
PMIB_IPADDRTABLE table;
|
||||
|
||||
if (!pIpAddrTable || *pdwSize < size) {
|
||||
*pdwSize = size;
|
||||
ret = ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
else {
|
||||
InterfaceIndexTable *table = getInterfaceIndexTable();
|
||||
ret = getIPAddrTable(&table, GetProcessHeap(), 0);
|
||||
if (ret == NO_ERROR)
|
||||
{
|
||||
ULONG size = sizeof(MIB_IPADDRTABLE) + (table->dwNumEntries - 1) *
|
||||
sizeof(MIB_IPADDRROW);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
TRACE("returning %ld\n", ret);
|
||||
|
@ -1102,30 +1125,6 @@ DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* GetIpForwardTable (IPHLPAPI.@)
|
||||
*
|
||||
|
@ -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;
|
||||
DWORD ret;
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(RouteTable) + (numRoutes - 1) * sizeof(RouteEntry));
|
||||
if (ret) {
|
||||
FILE *fp;
|
||||
if (!ppIpForwardTable)
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
else {
|
||||
DWORD numRoutes = getNumRoutes();
|
||||
PMIB_IPFORWARDTABLE table = HeapAlloc(heap, flags,
|
||||
sizeof(MIB_IPFORWARDTABLE) + (numRoutes - 1) * sizeof(MIB_IPFORWARDROW));
|
||||
|
||||
/* get from /proc/net/route, no error if can't */
|
||||
fp = fopen("/proc/net/route", "r");
|
||||
if (fp) {
|
||||
char buf[512] = { 0 }, *ptr;
|
||||
if (table) {
|
||||
FILE *fp;
|
||||
|
||||
/* skip header line */
|
||||
ptr = fgets(buf, sizeof(buf), fp);
|
||||
while (ptr && ret->numRoutes < numRoutes) {
|
||||
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 (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))
|
||||
while (!isspace(*ptr))
|
||||
ptr++;
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
if (getInterfaceIndexByName(buf, &index) == NO_ERROR) {
|
||||
char *endPtr;
|
||||
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;
|
||||
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].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 (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;
|
||||
DWORD ret;
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(MIB_IPNETTABLE) + (numEntries - 1) * sizeof(MIB_IPNETROW));
|
||||
if (ret) {
|
||||
FILE *fp;
|
||||
if (!ppIpNetTable)
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
else {
|
||||
DWORD numEntries = getNumArpEntries();
|
||||
PMIB_IPNETTABLE table = HeapAlloc(heap, flags,
|
||||
sizeof(MIB_IPNETTABLE) + (numEntries - 1) * sizeof(MIB_IPNETROW));
|
||||
|
||||
/* get from /proc/net/arp, no error if can't */
|
||||
fp = fopen("/proc/net/arp", "r");
|
||||
if (fp) {
|
||||
char buf[512] = { 0 }, *ptr;
|
||||
if (table) {
|
||||
FILE *fp;
|
||||
|
||||
/* skip header line */
|
||||
ptr = fgets(buf, sizeof(buf), fp);
|
||||
while (ptr && ret->dwNumEntries < numEntries) {
|
||||
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;
|
||||
table->table[table->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);
|
||||
|
||||
if (endPtr && *endPtr) {
|
||||
endPtr++;
|
||||
ret->table[ret->dwNumEntries].bPhysAddr[
|
||||
ret->table[ret->dwNumEntries].dwPhysAddrLen++] = byte & 0x0ff;
|
||||
ptr = endPtr;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
if (ptr && *ptr) {
|
||||
strtoul(ptr, &endPtr, 16); /* mask (skip) */
|
||||
ptr = endPtr;
|
||||
}
|
||||
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;
|
||||
DWORD ret;
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW));
|
||||
if (ret) {
|
||||
FILE *fp;
|
||||
if (!ppUdpTable)
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
else {
|
||||
DWORD numEntries = getNumUdpEntries();
|
||||
PMIB_UDPTABLE table = HeapAlloc(heap, flags,
|
||||
sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW));
|
||||
|
||||
/* get from /proc/net/udp, no error if can't */
|
||||
fp = fopen("/proc/net/udp", "r");
|
||||
if (fp) {
|
||||
char buf[512] = { 0 }, *ptr;
|
||||
if (table) {
|
||||
FILE *fp;
|
||||
|
||||
/* skip header line */
|
||||
ptr = fgets(buf, sizeof(buf), fp);
|
||||
while (ptr && ret->dwNumEntries < numEntries) {
|
||||
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) {
|
||||
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++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
DWORD ret;
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW));
|
||||
if (ret) {
|
||||
FILE *fp;
|
||||
if (!ppTcpTable)
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
else {
|
||||
DWORD numEntries = getNumTcpEntries();
|
||||
PMIB_TCPTABLE table = HeapAlloc(heap, flags,
|
||||
sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW));
|
||||
|
||||
/* get from /proc/net/tcp, no error if can't */
|
||||
fp = fopen("/proc/net/tcp", "r");
|
||||
if (fp) {
|
||||
char buf[512] = { 0 }, *ptr;
|
||||
if (table) {
|
||||
FILE *fp;
|
||||
|
||||
/* skip header line */
|
||||
ptr = fgets(buf, sizeof(buf), fp);
|
||||
while (ptr && ret->dwNumEntries < numEntries) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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.
|
||||
/* Allocates the route table from heap and returns it to you in
|
||||
* *ppIpForwardTable. Returns NO_ERROR on success, something else on failure.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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_ */
|
||||
|
|
Loading…
Reference in New Issue