Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938/* 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; }}
static NTSTATUStdiGetMibForIpEntity( _In_ HANDLE tcpFile, _In_ TDIEntityID *ent, _Out_ MIB_IPSTATS *entry){ TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; NTSTATUS Status; DWORD returnSize;
ZeroMemory(entry, 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->dwForwarding, entry->dwDefaultTTL, entry->dwInReceives, entry->dwInDelivers, entry->dwOutRequests, entry->dwRoutingDiscards, entry->dwOutDiscards, entry->dwOutNoRoutes, entry->dwNumIf, entry->dwNumAddr, entry->dwNumRoutes);
return Status;}
static NTSTATUStdiGetMibForTcpEntity( _In_ HANDLE tcpFile, _In_ TDIEntityID *ent, _Out_ MIB_TCPSTATS *entry){ TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; NTSTATUS Status; DWORD returnSize;
ZeroMemory(entry, sizeof(*entry));
TRACE("TdiGetMibForTcpEntity(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 = TCP_MIB_STAT_ID; req.ID.toi_entity = *ent;
Status = DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req, sizeof(req), entry, sizeof(*entry), &returnSize, NULL);
TRACE("TdiGetMibForTcpEntity() => status = 0x%08lx, entry = {\n" " dwInSegs ............. %lu\n" " dwOutSegs ............ %lu\n" " dwNumConns ........... %lu\n" "}\n", Status, entry->dwInSegs, entry->dwOutSegs, entry->dwNumConns);
return Status;}
static NTSTATUStdiGetMibForUdpEntity( _In_ HANDLE tcpFile, _In_ TDIEntityID *ent, _Out_ MIB_UDPSTATS *entry){ TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; NTSTATUS Status; DWORD returnSize;
ZeroMemory(entry, sizeof(*entry));
TRACE("TdiGetMibForUdpEntity(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 = UDP_MIB_STAT_ID; req.ID.toi_entity = *ent;
Status = DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req, sizeof(req), entry, sizeof(*entry), &returnSize, NULL);
TRACE("TdiGetMibForUdpEntity() => status = 0x%08lx, entry = {\n" " dwInDatagrams ....... %lu\n" " dwOutDatagrams ...... %lu\n" " dwNumAddrs .......... %lu\n" "}\n", Status, entry->dwInDatagrams, entry->dwOutDatagrams, entry->dwNumAddrs);
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 && _strnicmp(buf, hdr, sizeof(hdr) - 1)); if (ptr) { /* last line was a header, get another */ ptr = fgets(buf, sizeof(buf), fp); if (ptr && _strnicmp(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( _In_ HANDLE TcpFile, _Out_ PMIB_IPSTATS pStats){ TDIEntityID ent; NTSTATUS Status;
ent.tei_entity = CL_NL_ENTITY; ent.tei_instance = 0;
Status = tdiGetMibForIpEntity(TcpFile, &ent, pStats);
if (!NT_SUCCESS(Status)) return RtlNtStatusToDosError(Status);
return NO_ERROR;}
DWORD getTCPStats( _In_ HANDLE TcpFile, _Out_ MIB_TCPSTATS *pStats){ TDIEntityID ent; NTSTATUS Status;
ent.tei_entity = CO_TL_ENTITY; ent.tei_instance = 0;
Status = tdiGetMibForTcpEntity(TcpFile, &ent, pStats);
if (!NT_SUCCESS(Status)) return RtlNtStatusToDosError(Status);
return NO_ERROR;}
DWORD getUDPStats( _In_ HANDLE TcpFile, _Out_ MIB_UDPSTATS *pStats){ TDIEntityID ent; NTSTATUS Status;
ent.tei_entity = CL_TL_ENTITY; ent.tei_instance = 0;
Status = tdiGetMibForUdpEntity(TcpFile, &ent, pStats);
if (!NT_SUCCESS(Status)) return RtlNtStatusToDosError(Status);
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])) { MIB_IPSTATS ipstats; memset(&ipstats, 0, sizeof(ipstats)); status = tdiGetMibForIpEntity(tcpFile, &entitySet[i], &ipstats); if (!NT_SUCCESS(status)) { ERR("tdiGetMibForIpEntity returned 0x%08lx, for i = %d\n", status, i); numRoutes = 0; break; } numRoutes += ipstats.dwNumRoutes; } }
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;}