mirror of
https://github.com/reactos/reactos.git
synced 2024-11-02 12:53:33 +00:00
a5360f542f
- Strip inconsistent spaces from the spec file. - iphlpapi_main: Harmonize inconsistent and line-wasting function-comments and fix mixed space-tab-indentation. - ipstats_reactos.c: Compactify horizontally accordingly to the coding guidelines I am interested in that code for a backport, so I want it to be well-formatted. Ftr: IPHLPAPI was *forked* more than a decade ago from Wine. Therefore no diff ever was guarded within those files whenever we implemented anything here.
829 lines
24 KiB
C
829 lines
24 KiB
C
/* Copyright (C) 2003 Art Yerkes
|
|
* A reimplementation of ifenum.c by Juan Lang
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* This file is implemented on the IOCTL_TCP_QUERY_INFORMATION_EX ioctl on
|
|
* tcpip.sys
|
|
*/
|
|
|
|
#include "iphlpapi_private.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
|
|
|
|
#ifndef TCPS_ESTABLISHED
|
|
# define TCPS_ESTABLISHED TCP_ESTABLISHED
|
|
#endif
|
|
#ifndef TCPS_SYN_SENT
|
|
# define TCPS_SYN_SENT TCP_SYN_SENT
|
|
#endif
|
|
#ifndef TCPS_SYN_RECEIVED
|
|
# define TCPS_SYN_RECEIVED TCP_SYN_RECV
|
|
#endif
|
|
#ifndef TCPS_FIN_WAIT_1
|
|
# define TCPS_FIN_WAIT_1 TCP_FIN_WAIT1
|
|
#endif
|
|
#ifndef TCPS_FIN_WAIT_2
|
|
# define TCPS_FIN_WAIT_2 TCP_FIN_WAIT2
|
|
#endif
|
|
#ifndef TCPS_TIME_WAIT
|
|
# define TCPS_TIME_WAIT TCP_TIME_WAIT
|
|
#endif
|
|
#ifndef TCPS_CLOSED
|
|
# define TCPS_CLOSED TCP_CLOSE
|
|
#endif
|
|
#ifndef TCPS_CLOSE_WAIT
|
|
# define TCPS_CLOSE_WAIT TCP_CLOSE_WAIT
|
|
#endif
|
|
#ifndef TCPS_LAST_ACK
|
|
# define TCPS_LAST_ACK TCP_LAST_ACK
|
|
#endif
|
|
#ifndef TCPS_LISTEN
|
|
# define TCPS_LISTEN TCP_LISTEN
|
|
#endif
|
|
#ifndef TCPS_CLOSING
|
|
# define TCPS_CLOSING TCP_CLOSING
|
|
#endif
|
|
|
|
BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) {
|
|
return (ent->tei_entity == CL_NL_ENTITY ||
|
|
ent->tei_entity == CO_NL_ENTITY);
|
|
}
|
|
|
|
NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
|
|
DWORD numEntities = 0;
|
|
DWORD numRoutes = 0;
|
|
TDIEntityID *entitySet = 0;
|
|
NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
|
int i;
|
|
|
|
if( !NT_SUCCESS(status) )
|
|
return status;
|
|
|
|
for( i = 0; i < numEntities; i++ ) {
|
|
if( isIpEntity( tcpFile, &entitySet[i] ) ) {
|
|
TRACE("Entity %d is an IP Entity\n", i);
|
|
if( numRoutes == index ) break;
|
|
else numRoutes++;
|
|
}
|
|
}
|
|
|
|
if( numRoutes == index && i < numEntities ) {
|
|
TRACE("Index %lu is entity #%d - %04x:%08x\n", index, i,
|
|
entitySet[i].tei_entity, entitySet[i].tei_instance);
|
|
memcpy( ent, &entitySet[i], sizeof(*ent) );
|
|
tdiFreeThingSet( entitySet );
|
|
return STATUS_SUCCESS;
|
|
} else {
|
|
tdiFreeThingSet( entitySet );
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
|
|
NTSTATUS tdiGetMibForIpEntity
|
|
( HANDLE tcpFile, TDIEntityID *ent, IPSNMPInfo *entry ) {
|
|
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
DWORD returnSize;
|
|
|
|
memset( entry, 0, sizeof( *entry ) );
|
|
|
|
TRACE("TdiGetMibForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
|
|
tcpFile, ent->tei_instance);
|
|
|
|
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
|
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
|
req.ID.toi_id = IP_MIB_STATS_ID;
|
|
req.ID.toi_entity = *ent;
|
|
|
|
status = DeviceIoControl(tcpFile,
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
&req,
|
|
sizeof(req),
|
|
entry,
|
|
sizeof(*entry),
|
|
&returnSize,
|
|
NULL);
|
|
|
|
TRACE("TdiGetMibForIpEntity() => status = 0x%08lx, entry = {\n"
|
|
" ipsi_forwarding ............ %lu\n"
|
|
" ipsi_defaultttl ............ %lu\n"
|
|
" ipsi_inreceives ............ %lu\n"
|
|
" ipsi_indelivers ............ %lu\n"
|
|
" ipsi_outrequests ........... %lu\n"
|
|
" ipsi_routingdiscards ....... %lu\n"
|
|
" ipsi_outdiscards ........... %lu\n"
|
|
" ipsi_outnoroutes ........... %lu\n"
|
|
" ipsi_numif ................. %lu\n"
|
|
" ipsi_numaddr ............... %lu\n"
|
|
" ipsi_numroutes ............. %lu\n"
|
|
"}\n",
|
|
status,
|
|
entry->ipsi_forwarding,
|
|
entry->ipsi_defaultttl,
|
|
entry->ipsi_inreceives,
|
|
entry->ipsi_indelivers,
|
|
entry->ipsi_outrequests,
|
|
entry->ipsi_routingdiscards,
|
|
entry->ipsi_outdiscards,
|
|
entry->ipsi_outnoroutes,
|
|
entry->ipsi_numif,
|
|
entry->ipsi_numaddr,
|
|
entry->ipsi_numroutes);
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS tdiGetRoutesForIpEntity
|
|
( HANDLE tcpFile, TDIEntityID *ent, IPRouteEntry **routes, PDWORD numRoutes ) {
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
TRACE("TdiGetRoutesForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
|
|
tcpFile, ent->tei_instance);
|
|
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
IP_MIB_ARPTABLE_ENTRY_ID,
|
|
CL_NL_ENTITY,
|
|
ent->tei_instance,
|
|
0,
|
|
sizeof(IPRouteEntry),
|
|
(PVOID *)routes,
|
|
numRoutes);
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS tdiGetIpAddrsForIpEntity
|
|
( HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs, PDWORD numAddrs ) {
|
|
NTSTATUS status;
|
|
|
|
TRACE("TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
|
|
tcpFile, ent->tei_instance);
|
|
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
IP_MIB_ADDRTABLE_ENTRY_ID,
|
|
CL_NL_ENTITY,
|
|
ent->tei_instance,
|
|
0,
|
|
sizeof(IPAddrEntry),
|
|
(PVOID *)addrs,
|
|
numAddrs);
|
|
|
|
return status;
|
|
}
|
|
|
|
DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
|
|
{
|
|
if (!name)
|
|
return ERROR_INVALID_PARAMETER;
|
|
if (!entry)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD getInterfaceStatsByIndex(DWORD index, PMIB_IFROW entry)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
DWORD getICMPStats(MIB_ICMP *stats)
|
|
{
|
|
FILE *fp;
|
|
|
|
if (!stats)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
memset(stats, 0, sizeof(MIB_ICMP));
|
|
/* get most of these stats from /proc/net/snmp, no error if can't */
|
|
fp = fopen("/proc/net/snmp", "r");
|
|
if (fp) {
|
|
const char hdr[] = "Icmp:";
|
|
char buf[512] = { 0 }, *ptr;
|
|
|
|
do {
|
|
ptr = fgets(buf, sizeof(buf), fp);
|
|
} while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
|
|
if (ptr) {
|
|
/* last line was a header, get another */
|
|
ptr = fgets(buf, sizeof(buf), fp);
|
|
if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
|
|
char *endPtr;
|
|
|
|
ptr += sizeof(hdr);
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
if (ptr && *ptr) {
|
|
stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
|
|
ptr = endPtr;
|
|
}
|
|
}
|
|
}
|
|
fclose(fp);
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD getIPStats(PMIB_IPSTATS stats, DWORD family)
|
|
{
|
|
if (!stats)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
if (family != AF_INET && family != AF_INET6)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD getTCPStats(MIB_TCPSTATS *stats, DWORD family)
|
|
{
|
|
if (!stats)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
if (family != AF_INET && family != AF_INET6)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family)
|
|
{
|
|
if (!stats)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
if (family != AF_INET && family != AF_INET6)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD getNumRoutes(void)
|
|
{
|
|
DWORD numEntities, numRoutes = 0;
|
|
TDIEntityID *entitySet;
|
|
HANDLE tcpFile;
|
|
int i;
|
|
NTSTATUS status;
|
|
|
|
TRACE("called.\n");
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
if (!NT_SUCCESS(status)) {
|
|
ERR("tdiGetEntityIDSet returned 0x%08lx\n", status);
|
|
closeTcpFile( tcpFile );
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (isIpEntity(tcpFile, &entitySet[i])) {
|
|
IPSNMPInfo isnmp;
|
|
memset(&isnmp, 0, sizeof(isnmp));
|
|
status = tdiGetMibForIpEntity(tcpFile, &entitySet[i], &isnmp);
|
|
if (!NT_SUCCESS(status)) {
|
|
ERR("tdiGetMibForIpEntity returned 0x%08lx, for i = %d\n", status, i);
|
|
numRoutes = 0;
|
|
break;
|
|
}
|
|
numRoutes += isnmp.ipsi_numroutes;
|
|
}
|
|
}
|
|
|
|
TRACE("numRoutes = %lu\n", numRoutes);
|
|
|
|
tdiFreeThingSet(entitySet);
|
|
closeTcpFile(tcpFile);
|
|
|
|
return numRoutes;
|
|
}
|
|
|
|
VOID HexDump( PCHAR Data, DWORD Len ) {
|
|
int i;
|
|
|
|
for( i = 0; i < Len; i++ ) {
|
|
if( !(i & 0xf) ) {
|
|
if( i ) fprintf(stderr,"\n");
|
|
fprintf(stderr,"%08x:", i);
|
|
}
|
|
fprintf( stderr, " %02x", Data[i] & 0xff );
|
|
}
|
|
fprintf(stderr,"\n");
|
|
}
|
|
|
|
RouteTable *getRouteTable(void)
|
|
{
|
|
RouteTable *out_route_table;
|
|
DWORD numRoutes = getNumRoutes(), routesAdded = 0;
|
|
TDIEntityID ent;
|
|
HANDLE tcpFile;
|
|
NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
int i;
|
|
|
|
if (!NT_SUCCESS(status))
|
|
return 0;
|
|
|
|
TRACE("GETTING ROUTE TABLE\n");
|
|
|
|
out_route_table = HeapAlloc(GetProcessHeap(), 0,
|
|
sizeof(RouteTable) +
|
|
(sizeof(RouteEntry) * (numRoutes - 1)));
|
|
if (!out_route_table) {
|
|
closeTcpFile(tcpFile);
|
|
return NULL;
|
|
}
|
|
|
|
out_route_table->numRoutes = numRoutes;
|
|
|
|
for (i = 0; routesAdded < out_route_table->numRoutes; i++) {
|
|
int j;
|
|
IPRouteEntry *route_set;
|
|
|
|
getNthIpEntity(tcpFile, i, &ent);
|
|
|
|
tdiGetRoutesForIpEntity(tcpFile, &ent, &route_set, &numRoutes);
|
|
if (!route_set) {
|
|
closeTcpFile(tcpFile);
|
|
HeapFree(GetProcessHeap(), 0, out_route_table);
|
|
return 0;
|
|
}
|
|
|
|
TRACE("%lu routes in instance %d\n", numRoutes, i);
|
|
#if 0
|
|
HexDump(route_set,
|
|
sizeof(IPRouteEntry) *
|
|
snmpInfo.ipsi_numroutes);
|
|
#endif
|
|
|
|
for (j = 0; j < numRoutes; j++) {
|
|
int routeNum = j + routesAdded;
|
|
out_route_table->routes[routeNum].dest =
|
|
route_set[j].ire_dest;
|
|
out_route_table->routes[routeNum].mask =
|
|
route_set[j].ire_mask;
|
|
out_route_table->routes[routeNum].gateway =
|
|
route_set[j].ire_gw;
|
|
out_route_table->routes[routeNum].ifIndex =
|
|
route_set[j].ire_index;
|
|
out_route_table->routes[routeNum].metric =
|
|
route_set[j].ire_metric1;
|
|
}
|
|
|
|
if (route_set) tdiFreeThingSet(route_set);
|
|
|
|
routesAdded += numRoutes;
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
TRACE("status = 0x%08lx, out_route_table = 0x%p\n", status, out_route_table);
|
|
return out_route_table;
|
|
}
|
|
|
|
DWORD getNumArpEntries(void)
|
|
{
|
|
DWORD numEntities;
|
|
TDIEntityID *entitySet = NULL;
|
|
HANDLE tcpFile;
|
|
int i, totalNumber = 0;
|
|
NTSTATUS status;
|
|
PMIB_IPNETROW IpArpTable = NULL;
|
|
DWORD returnSize;
|
|
|
|
TRACE("called.\n");
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (isInterface(&entitySet[i]) && hasArp(tcpFile, &entitySet[i]))
|
|
{
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
IP_MIB_ARPTABLE_ENTRY_ID,
|
|
AT_ENTITY,
|
|
entitySet[i].tei_instance,
|
|
0,
|
|
sizeof(MIB_IPNETROW),
|
|
(PVOID *)&IpArpTable,
|
|
&returnSize);
|
|
|
|
if (status == STATUS_SUCCESS) totalNumber += returnSize;
|
|
if (IpArpTable) {
|
|
tdiFreeThingSet(IpArpTable);
|
|
IpArpTable = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
if (entitySet) tdiFreeThingSet(entitySet);
|
|
return totalNumber;
|
|
}
|
|
|
|
PMIB_IPNETTABLE getArpTable(void)
|
|
{
|
|
DWORD numEntities, returnSize;
|
|
TDIEntityID *entitySet;
|
|
HANDLE tcpFile;
|
|
int i, totalNumber, TmpIdx, CurrIdx = 0;
|
|
NTSTATUS status;
|
|
PMIB_IPNETTABLE IpArpTable = NULL;
|
|
PMIB_IPNETROW AdapterArpTable = NULL;
|
|
|
|
TRACE("called.\n");
|
|
|
|
totalNumber = getNumArpEntries();
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
IpArpTable = HeapAlloc(GetProcessHeap(), 0,
|
|
sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber));
|
|
if (!IpArpTable) {
|
|
closeTcpFile(tcpFile);
|
|
return NULL;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (isInterface(&entitySet[i]) && hasArp(tcpFile, &entitySet[i]))
|
|
{
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
IP_MIB_ARPTABLE_ENTRY_ID,
|
|
AT_ENTITY,
|
|
entitySet[i].tei_instance,
|
|
0,
|
|
sizeof(MIB_IPNETROW),
|
|
(PVOID *)&AdapterArpTable,
|
|
&returnSize);
|
|
|
|
if (status == STATUS_SUCCESS) {
|
|
for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
|
|
IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx];
|
|
tdiFreeThingSet(AdapterArpTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
tdiFreeThingSet(entitySet);
|
|
IpArpTable->dwNumEntries = CurrIdx;
|
|
return IpArpTable;
|
|
}
|
|
|
|
struct _TABLE_CALL
|
|
{
|
|
DWORD TOIID;
|
|
SIZE_T UdpSize;
|
|
SIZE_T TcpSize;
|
|
SIZE_T UdpOffset;
|
|
SIZE_T TcpOffset;
|
|
} UdpTcpTableCall[] = {
|
|
{IP_MIB_ARPTABLE_ENTRY_ID, sizeof(MIB_UDPROW), sizeof(MIB_TCPROW), FIELD_OFFSET(MIB_UDPTABLE, table), FIELD_OFFSET(MIB_TCPTABLE, table)},
|
|
{IP_MIB_ADDRTABLE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_PID), sizeof(MIB_TCPROW_OWNER_PID), FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table)},
|
|
{IP_SPECIFIC_MODULE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_MODULE), sizeof(MIB_TCPROW_OWNER_MODULE), FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table)},
|
|
};
|
|
|
|
#define Add2Ptr(PTR, INC) (PVOID)((ULONG_PTR)(PTR) + (INC))
|
|
|
|
DWORD getNumUdpEntries(void)
|
|
{
|
|
DWORD numEntities;
|
|
TDIEntityID *entitySet = NULL;
|
|
HANDLE tcpFile;
|
|
int i, totalNumber = 0;
|
|
NTSTATUS status;
|
|
PMIB_UDPROW IpUdpTable = NULL;
|
|
DWORD returnSize;
|
|
|
|
TRACE("called.\n");
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (entitySet[i].tei_entity == CL_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
|
|
{
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
IP_MIB_ARPTABLE_ENTRY_ID,
|
|
CL_TL_ENTITY,
|
|
entitySet[i].tei_instance,
|
|
0,
|
|
sizeof(MIB_UDPROW),
|
|
(PVOID *)&IpUdpTable,
|
|
&returnSize);
|
|
|
|
if (status == STATUS_SUCCESS) totalNumber += returnSize;
|
|
if (IpUdpTable) {
|
|
tdiFreeThingSet(IpUdpTable);
|
|
IpUdpTable = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
if (entitySet) tdiFreeThingSet(entitySet);
|
|
return totalNumber;
|
|
}
|
|
|
|
PVOID getUdpTable(CLASS_TABLE Class)
|
|
{
|
|
DWORD numEntities, returnSize;
|
|
TDIEntityID *entitySet;
|
|
HANDLE tcpFile;
|
|
int i, totalNumber, TmpIdx, CurrIdx = 0;
|
|
NTSTATUS status;
|
|
PMIB_UDPTABLE IpUdpTable = NULL;
|
|
PVOID AdapterUdpTable = NULL;
|
|
|
|
TRACE("called.\n");
|
|
|
|
totalNumber = getNumUdpEntries();
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
IpUdpTable = HeapAlloc(GetProcessHeap(), 0,
|
|
UdpTcpTableCall[Class].UdpOffset + (UdpTcpTableCall[Class].UdpSize * totalNumber));
|
|
if (!IpUdpTable) {
|
|
closeTcpFile(tcpFile);
|
|
return NULL;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (entitySet[i].tei_entity == CL_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
|
|
{
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
UdpTcpTableCall[Class].TOIID,
|
|
CL_TL_ENTITY,
|
|
entitySet[i].tei_instance,
|
|
0,
|
|
UdpTcpTableCall[Class].UdpSize,
|
|
&AdapterUdpTable,
|
|
&returnSize);
|
|
|
|
if (status == STATUS_SUCCESS) {
|
|
for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
|
|
CopyMemory(Add2Ptr(IpUdpTable, UdpTcpTableCall[Class].UdpOffset + UdpTcpTableCall[Class].UdpSize * CurrIdx),
|
|
Add2Ptr(AdapterUdpTable, UdpTcpTableCall[Class].UdpSize * TmpIdx),
|
|
UdpTcpTableCall[Class].UdpSize);
|
|
tdiFreeThingSet(AdapterUdpTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
tdiFreeThingSet(entitySet);
|
|
IpUdpTable->dwNumEntries = CurrIdx;
|
|
return IpUdpTable;
|
|
}
|
|
|
|
DWORD getNumTcpEntries(void)
|
|
{
|
|
DWORD numEntities;
|
|
TDIEntityID *entitySet = NULL;
|
|
HANDLE tcpFile;
|
|
int i, totalNumber = 0;
|
|
NTSTATUS status;
|
|
PMIB_TCPROW IpTcpTable = NULL;
|
|
DWORD returnSize;
|
|
|
|
TRACE("called.\n");
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (entitySet[i].tei_entity == CO_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
|
|
{
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
IP_MIB_ARPTABLE_ENTRY_ID,
|
|
CO_TL_ENTITY,
|
|
entitySet[i].tei_instance,
|
|
0,
|
|
sizeof(MIB_TCPROW),
|
|
(PVOID *)&IpTcpTable,
|
|
&returnSize);
|
|
|
|
if (status == STATUS_SUCCESS) totalNumber += returnSize;
|
|
if (IpTcpTable) {
|
|
tdiFreeThingSet(IpTcpTable);
|
|
IpTcpTable = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
if (entitySet) tdiFreeThingSet(entitySet);
|
|
return totalNumber;
|
|
}
|
|
|
|
PVOID getTcpTable(CLASS_TABLE Class)
|
|
{
|
|
DWORD numEntities, returnSize;
|
|
TDIEntityID *entitySet;
|
|
HANDLE tcpFile;
|
|
int i, totalNumber, TmpIdx, CurrIdx = 0;
|
|
NTSTATUS status;
|
|
PMIB_TCPTABLE IpTcpTable = NULL;
|
|
PVOID AdapterTcpTable = NULL;
|
|
|
|
TRACE("called.\n");
|
|
|
|
totalNumber = getNumTcpEntries();
|
|
|
|
status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ERR("openTcpFile returned 0x%08lx\n", status);
|
|
return 0;
|
|
}
|
|
|
|
IpTcpTable = HeapAlloc(GetProcessHeap(), 0,
|
|
UdpTcpTableCall[Class].TcpOffset + (UdpTcpTableCall[Class].TcpSize * totalNumber));
|
|
if (!IpTcpTable) {
|
|
closeTcpFile(tcpFile);
|
|
return NULL;
|
|
}
|
|
|
|
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
|
|
|
for (i = 0; i < numEntities; i++) {
|
|
if (entitySet[i].tei_entity == CO_TL_ENTITY && hasArp(tcpFile, &entitySet[i]))
|
|
{
|
|
status = tdiGetSetOfThings(tcpFile,
|
|
INFO_CLASS_PROTOCOL,
|
|
INFO_TYPE_PROVIDER,
|
|
UdpTcpTableCall[Class].TOIID,
|
|
CO_TL_ENTITY,
|
|
entitySet[i].tei_instance,
|
|
0,
|
|
UdpTcpTableCall[Class].TcpSize,
|
|
&AdapterTcpTable,
|
|
&returnSize);
|
|
|
|
if (status == STATUS_SUCCESS) {
|
|
for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
|
|
CopyMemory(Add2Ptr(IpTcpTable, UdpTcpTableCall[Class].TcpOffset + UdpTcpTableCall[Class].TcpSize * CurrIdx),
|
|
Add2Ptr(AdapterTcpTable, UdpTcpTableCall[Class].TcpSize * TmpIdx),
|
|
UdpTcpTableCall[Class].TcpSize);
|
|
tdiFreeThingSet(AdapterTcpTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
tdiFreeThingSet(entitySet);
|
|
IpTcpTable->dwNumEntries = CurrIdx;
|
|
return IpTcpTable;
|
|
}
|