[0.4.7][IPHLPAPI][TCPIP][IP][LWIP][SDK][PSDK] Port back groundworks for netstat

This fixes:
CORE-15363 'netstat TCP foreign address port is wrong'
CORE-5401 'Netstat returns ERROR_NO_DATA Pipe being closed'
CORE-5126 'UNIMPLEMENTED: iphlpapi: GetExtendedUdpTable'
even without touching the netstat binary yet.
And is mostly based on work done by Pierre Schweitzer during 0.4.11-dev'ing.

by porting back:
0.4.15-dev-6231-g a5360f542f [IPHLPAPI] Formatting only, no functional change
partially 0.4.14-dev-1425-g f540b2b20c [IPHLPAPI] GetAdaptersAddresses(): Add 1 free() in ERROR_NO_DATA case (#2526) (but leave out adding the comments in .h)
0.4.12-dev-686-g 22f60faf43 [IPHLPAPI] Remove dead code to fix CID 513306, 1442673, 1442697
0.4.11-dev-880-g bf052e120b [IPHLPAPI] Reduce code duplication and use a single function for TCP and UDP enumerations + fix corruption
0.4.11-dev-867-g 159f5b676a [IPHLPAPI] Fix broken size computation leading to buffer overrun
0.4.11-dev-861-g 05657bfcfd [SDK] Add a non documenter TOIID used to query modules information
0.4.11-dev-827-g ce7f9211a0 [TCPIP] In InfoTdiQueryGetConnectionTcpTable(), only return if there's a connection
0.4.11-dev-823-g 0ec92100bc [TCPIP] Properly display local information for established connections
0.4.11-dev-819-g fbdfe7bd40 [SDK] Add GetExtendedUdpTable()
0.4.11-dev-818-g 370b03b523 [IPHLPAPI] Reimplement GetUdpTable() using GetExtendedUdpTable()
0.4.11-dev-817-g 58cef01422 [IPHLPAPI] Implement GetExtendedUdpTable() CORE-5126
0.4.11-dev-816-g 6fb6c7b50b [IPHLPAPI] Implement getOwnerUdoTable(), to get UDP connections with owner PID
0.4.11-dev-815-g 13de7f08af [TCPIP] Implement enumerating UDP connections with owner PID
0.4.11-dev-813-g 73c87d5c14 [IPHLPAPI] Reimplement GetTcpTable() using GetExtendedTcpTable()
0.4.11-dev-812-g d76ac645e8 [IPHLPAPI] Don't leak memory
0.4.11-dev-811-g c949a12506 [IPHLPAPI] Implement the IPv4 TCP_TABLE_OWNER_PID_* cases in GetExtendedTcpTable()
0.4.11-dev-810-g dca7e5689f [IPHLPAPI] Implement getOwnerTcpTable(), to get TCP connections with owner PID
0.4.11-dev-809-g 411504b5f4 [TCPIP] Implement enumerating TCP connections with owner PID
0.4.11-dev-808-g 935978ee57 [TCPIP] Store creator PID in ADDRESS_FILE
0.4.11-dev-807-g 702d44c683 [IPHLPAPI] Implement the IPv4 TCP_TABLE_BASIC_* cases in GetExtendedTcpTable()
0.4.11-dev-804-g 91b013d387 [TCPIP] When enumerating sockets, retrieve their state and return it
0.4.11-dev-803-g 738f327668 [IP] Add a TCPGetSocketStatus() wrapper around LibTCPGetSocketStatus()
0.4.11-dev-802-g 29c1510423 [LWIP] Implement a LibTCPGetSocketStatus() function in our LwIP glue
0.4.11-dev-792-g 8a98c85c1f [IPHLPAPI] Fix checking entity when enumerating TCP/UDP connections
0.4.11-dev-784-g f29016dabe [TCPIP] Properly handle listening sockets
0.4.11-dev-782-g 007f43dd56 [TCPIP] Implement returning UDP connections CORE-5401
0.4.11-dev-781-g 77d5f04f22 [TCPIP] Implement returning TCP connections CORE-5401
0.4.11-dev-799-g 500a5151ea [TCPIP] Fix returned IP address when querying TCP connections CORE-15363
0.4.11-dev-783-g d18b1fe24b [IPHLPAPI] Properly count UDP entries CORE-5401
0.4.11-dev-780-g e3cb9697a4 [IPHLPAPI] Implement getNumUdpEntries() and getUdpTable() CORE-5401
0.4.11-dev-779-g 678204790c [IPHLPAPI] Implement getNumTcpEntries() and getTcpTable() CORE-5401
0.4.9-dev-59-g b6c060ce04 [IPHLPAPI] Fix getNumRoutes() return value on Mib error (#391)
----------------
Strip some DPRINTs entirely in IPHLPAPI/TCPIP in releases/0.4.7 - 0.4.10 (instead of fixing them like we did on master). Many of them had x64 issues:
This was partially *inspired* by watching the following commits:
0.4.13-dev-14-g f9a967b2ae [IPHLPAPI] Fix misc 64 bit issues (only the parts in iphlpapi_main.c with the format strings)
0.4.10-dev-409-g 0f8439aa71 [IPHLPAPI] Fix 64 bit issue, just the one within [IPHLPAPI] ifenum_reactos.c
0.4.9-dev-856-g 6c9359221c [IPHLPAPI] ipstats_reactos: Review all TRACE/WARN calls
This does not only fix the x64 incompatibilities by superseding those 3 commits but also will keep the file-sizes under control for the backports.
This commit is contained in:
Joachim Henze 2023-07-03 01:57:54 +02:00
parent 6812097a8b
commit 40bbab2b8c
17 changed files with 903 additions and 757 deletions

View file

@ -62,9 +62,6 @@ NTSTATUS tdiGetMibForIfEntity
NTSTATUS status = STATUS_SUCCESS;
DWORD returnSize;
WARN("TdiGetMibForIfEntity(tcpFile %x,entityId %x)\n",
(int)tcpFile, (int)ent->tei_instance);
req.ID.toi_class = INFO_CLASS_PROTOCOL;
req.ID.toi_type = INFO_TYPE_PROVIDER;
req.ID.toi_id = IF_MIB_STATS_ID;

View file

@ -1,84 +1,84 @@
@ stdcall AddIPAddress( long long long ptr ptr )
@ stdcall AddIPAddress(long long long ptr ptr)
@ stub AllocateAndGetArpEntTableFromStack
@ stdcall AllocateAndGetIfTableFromStack( ptr long long long )
@ stdcall AllocateAndGetIpAddrTableFromStack( ptr long long long )
@ stdcall AllocateAndGetIpForwardTableFromStack( ptr long long long )
@ stdcall AllocateAndGetIpNetTableFromStack( ptr long long long )
@ stdcall AllocateAndGetIfTableFromStack(ptr long long long)
@ stdcall AllocateAndGetIpAddrTableFromStack(ptr long long long)
@ stdcall AllocateAndGetIpForwardTableFromStack(ptr long long long)
@ stdcall AllocateAndGetIpNetTableFromStack(ptr long long long)
@ stub AllocateAndGetTcpExTable2FromStack
@ stub AllocateAndGetTcpExTableFromStack
@ stdcall AllocateAndGetTcpTableFromStack( ptr long long long )
@ stdcall AllocateAndGetTcpTableFromStack(ptr long long long)
@ stub AllocateAndGetUdpExTable2FromStack
@ stub AllocateAndGetUdpExTableFromStack
@ stdcall AllocateAndGetUdpTableFromStack( ptr long long long )
@ stdcall AllocateAndGetUdpTableFromStack(ptr long long long)
@ stdcall CancelIPChangeNotify(ptr)
@ stub CancelSecurityHealthChangeNotify
@ stdcall CreateIpForwardEntry( ptr )
@ stdcall CreateIpNetEntry( ptr )
@ stdcall CreateProxyArpEntry( long long long )
@ stdcall DeleteIPAddress( long )
@ stdcall DeleteIpForwardEntry( ptr )
@ stdcall DeleteIpNetEntry( ptr )
@ stdcall DeleteProxyArpEntry( long long long )
@ stdcall CreateIpForwardEntry(ptr)
@ stdcall CreateIpNetEntry(ptr)
@ stdcall CreateProxyArpEntry(long long long)
@ stdcall DeleteIPAddress(long)
@ stdcall DeleteIpForwardEntry(ptr)
@ stdcall DeleteIpNetEntry(ptr)
@ stdcall DeleteProxyArpEntry(long long long)
@ stdcall DisableMediaSense(ptr ptr)
@ stdcall EnableRouter( ptr ptr )
@ stdcall FlushIpNetTable( long )
@ stdcall EnableRouter(ptr ptr)
@ stdcall FlushIpNetTable(long)
@ stub FlushIpNetTableFromStack
@ stdcall GetAdapterIndex( wstr ptr )
@ stdcall GetAdapterIndex(wstr ptr)
@ stdcall GetAdapterOrderMap()
@ stdcall GetAdaptersAddresses( long long ptr ptr ptr )
@ stdcall GetAdaptersInfo( ptr ptr )
@ stdcall GetBestInterface( long ptr )
@ stdcall GetAdaptersAddresses(long long ptr ptr ptr)
@ stdcall GetAdaptersInfo(ptr ptr)
@ stdcall GetBestInterface(long ptr)
@ stdcall GetBestInterfaceEx(ptr ptr)
@ stub GetBestInterfaceFromStack
@ stdcall GetBestRoute( long long long )
@ stdcall GetBestRoute(long long long)
@ stub GetBestRouteFromStack
@ stdcall GetExtendedTcpTable( ptr ptr long long long long )
@ stdcall -stub GetExtendedUdpTable( ptr ptr long long long long )
@ stdcall GetFriendlyIfIndex( long )
@ stdcall GetIcmpStatistics( ptr )
@ stdcall GetExtendedTcpTable(ptr ptr long long long long)
@ stdcall GetExtendedUdpTable(ptr ptr long long long long)
@ stdcall GetFriendlyIfIndex(long)
@ stdcall GetIcmpStatistics(ptr)
@ stdcall GetIcmpStatisticsEx(ptr long)
@ stub GetIcmpStatsFromStack
@ stub GetIcmpStatsFromStackEx
@ stdcall GetIfEntry( ptr )
@ stdcall GetIfEntry(ptr)
@ stub GetIfEntryFromStack
@ stdcall GetIfTable( ptr ptr long )
@ stdcall GetIfTable(ptr ptr long)
@ stub GetIfTableFromStack
@ stub GetIgmpList
@ stdcall GetInterfaceInfo( ptr ptr )
@ stdcall GetIpAddrTable( ptr ptr long )
@ stdcall GetInterfaceInfo(ptr ptr)
@ stdcall GetIpAddrTable(ptr ptr long)
@ stub GetIpAddrTableFromStack
@ stdcall GetIpErrorString(long ptr ptr)
@ stdcall GetIpForwardTable( ptr ptr long )
@ stdcall GetIpForwardTable(ptr ptr long)
@ stub GetIpForwardTableFromStack
@ stdcall GetIpNetTable( ptr ptr long )
@ stdcall GetIpNetTable(ptr ptr long)
@ stub GetIpNetTableFromStack
@ stdcall GetIpStatistics( ptr )
@ stdcall GetIpStatistics(ptr)
@ stdcall GetIpStatisticsEx(ptr long)
@ stub GetIpStatsFromStack
@ stub GetIpStatsFromStackEx
@ stdcall GetNetworkParams( ptr ptr )
@ stdcall GetNumberOfInterfaces( ptr )
@ stdcall GetNetworkParams(ptr ptr)
@ stdcall GetNumberOfInterfaces(ptr)
@ stub GetOwnerModuleFromTcp6Entry
@ stdcall GetOwnerModuleFromTcpEntry ( ptr long ptr ptr )
@ stdcall GetOwnerModuleFromTcpEntry(ptr long ptr ptr)
@ stub GetOwnerModuleFromUdp6Entry
@ stub GetOwnerModuleFromUdpEntry
@ stdcall GetPerAdapterInfo( long ptr ptr )
@ stdcall GetRTTAndHopCount( long ptr long ptr )
@ stdcall GetPerAdapterInfo(long ptr ptr)
@ stdcall GetRTTAndHopCount(long ptr long ptr)
@ stub GetTcpExTable2FromStack
@ stdcall GetTcpStatistics( ptr )
@ stdcall GetTcpStatistics(ptr)
@ stdcall GetTcpStatisticsEx(ptr long)
@ stub GetTcpStatsFromStack
@ stub GetTcpStatsFromStackEx
@ stdcall GetTcpTable( ptr ptr long )
@ stdcall GetTcpTable(ptr ptr long)
@ stub GetTcpTableFromStack
@ stub GetUdpExTable2FromStack
@ stdcall GetUdpStatistics( ptr )
@ stdcall GetUdpStatistics(ptr)
@ stdcall GetUdpStatisticsEx(ptr long)
@ stub GetUdpStatsFromStack
@ stub GetUdpStatsFromStackEx
@ stdcall GetUdpTable( ptr ptr long )
@ stdcall GetUdpTable(ptr ptr long)
@ stub GetUdpTableFromStack
@ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
@ stdcall GetUniDirectionalAdapterInfo(ptr ptr)
@ stdcall Icmp6CreateFile()
@ stdcall -stub Icmp6ParseReplies(ptr long)
@ stdcall Icmp6SendEcho2(ptr ptr ptr ptr ptr ptr ptr long ptr ptr long long)
@ -102,8 +102,8 @@
@ stub InternalSetIpNetEntry
@ stub InternalSetIpStats
@ stub InternalSetTcpEntry
@ stdcall IpReleaseAddress( ptr )
@ stdcall IpRenewAddress( ptr )
@ stdcall IpReleaseAddress(ptr)
@ stdcall IpRenewAddress(ptr)
@ stub IsLocalAddress
@ stub NTPTimeToNTFileTime
@ stub NTTimeToNTPTime
@ -112,30 +112,30 @@
@ stub NhGetInterfaceNameFromGuid
@ stdcall NhpAllocateAndGetInterfaceInfoFromStack(ptr ptr long ptr long)
@ stub NhpGetInterfaceIndexFromStack
@ stdcall NotifyAddrChange( ptr ptr )
@ stdcall NotifyRouteChange( ptr ptr )
@ stdcall NotifyAddrChange(ptr ptr)
@ stdcall NotifyRouteChange(ptr ptr)
@ stub NotifyRouteChangeEx
@ stub NotifySecurityHealthChange
@ stdcall RestoreMediaSense(ptr ptr)
@ stdcall SendARP(long long ptr ptr)
@ stub SetAdapterIpAddress
@ stub SetBlockRoutes
@ stdcall SetIfEntry( ptr )
@ stdcall SetIfEntry(ptr)
@ stub SetIfEntryToStack
@ stdcall SetIpForwardEntry( ptr )
@ stdcall SetIpForwardEntryToStack( ptr )
@ stdcall SetIpForwardEntry(ptr)
@ stdcall SetIpForwardEntryToStack(ptr)
@ stub SetIpMultihopRouteEntryToStack
@ stdcall SetIpNetEntry( ptr )
@ stdcall SetIpNetEntry(ptr)
@ stub SetIpNetEntryToStack
@ stub SetIpRouteEntryToStack
@ stdcall SetIpStatistics( ptr )
@ stdcall SetIpStatistics(ptr)
@ stub SetIpStatsToStack
@ stdcall SetIpTTL( long )
@ stdcall SetIpTTL(long)
@ stub SetProxyArpEntryToStack
@ stub SetRouteWithRef
@ stdcall SetTcpEntry( ptr )
@ stdcall SetTcpEntry(ptr)
@ stub SetTcpEntryToStack
@ stdcall UnenableRouter( ptr ptr )
@ stdcall UnenableRouter(ptr ptr)
@ stub _PfAddFiltersToInterface@24
@ stub _PfAddGlobalFilterToInterface@8
@ stub _PfBindInterfaceToIPAddress@12

File diff suppressed because it is too large Load diff

View file

@ -76,6 +76,12 @@ typedef struct _RouteTable {
RouteEntry routes[1];
} RouteTable;
typedef enum _CLASS_TABLE {
ClassBasic,
ClassModulePid,
ClassModule
} CLASS_TABLE;
/* Allocates and returns to you the route table, or NULL if it can't allocate
* enough memory. free() the returned table.
*/
@ -95,7 +101,7 @@ DWORD getNumUdpEntries(void);
/* Allocates and returns to you the UDP state table, or NULL if it can't
* allocate enough memory. free() the returned table.
*/
PMIB_UDPTABLE getUdpTable(void);
PVOID getUdpTable(CLASS_TABLE Class);
/* Returns the number of entries in the TCP state table. */
DWORD getNumTcpEntries(void);
@ -103,6 +109,6 @@ DWORD getNumTcpEntries(void);
/* Allocates and returns to you the TCP state table, or NULL if it can't
* allocate enough memory. free() the returned table.
*/
PMIB_TCPTABLE getTcpTable(void);
PVOID getTcpTable(CLASS_TABLE Class);
#endif /* ndef WINE_IPSTATS_H_ */

View file

@ -74,15 +74,12 @@ NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
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 %d 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;
@ -100,48 +97,19 @@ NTSTATUS tdiGetMibForIpEntity
memset( entry, 0, sizeof( *entry ) );
TRACE("TdiGetMibForIpEntity(tcpFile %x,entityId %x)\n",
(DWORD)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() => {\n"
" ipsi_forwarding ............ %d\n"
" ipsi_defaultttl ............ %d\n"
" ipsi_inreceives ............ %d\n"
" ipsi_indelivers ............ %d\n"
" ipsi_outrequests ........... %d\n"
" ipsi_routingdiscards ....... %d\n"
" ipsi_outdiscards ........... %d\n"
" ipsi_outnoroutes ........... %d\n"
" ipsi_numif ................. %d\n"
" ipsi_numaddr ............... %d\n"
" ipsi_numroutes ............. %d\n"
"} status %08x\n",
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,
status);
status = DeviceIoControl(tcpFile,
IOCTL_TCP_QUERY_INFORMATION_EX,
&req,
sizeof(req),
entry,
sizeof(*entry),
&returnSize,
NULL);
return status;
}
@ -150,19 +118,16 @@ NTSTATUS tdiGetRoutesForIpEntity
( HANDLE tcpFile, TDIEntityID *ent, IPRouteEntry **routes, PDWORD numRoutes ) {
NTSTATUS status = STATUS_SUCCESS;
TRACE("TdiGetRoutesForIpEntity(tcpFile %x,entityId %x)\n",
(DWORD)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);
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;
}
@ -171,19 +136,16 @@ NTSTATUS tdiGetIpAddrsForIpEntity
( HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs, PDWORD numAddrs ) {
NTSTATUS status;
TRACE("TdiGetIpAddrsForIpEntity(tcpFile %x,entityId %x)\n",
(DWORD)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 );
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;
}
@ -351,11 +313,6 @@ DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family)
return NO_ERROR;
}
static DWORD getNumWithOneHeader(const char *filename)
{
return 0;
}
DWORD getNumRoutes(void)
{
DWORD numEntities, numRoutes = 0;
@ -364,75 +321,50 @@ DWORD getNumRoutes(void)
int i;
NTSTATUS status;
TRACE("called.\n");
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
TRACE("failure: %08x\n", (int)status );
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(status))
return 0;
}
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
if( !NT_SUCCESS(status) ) {
TRACE("failure: %08x\n", (int)status );
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
if (!NT_SUCCESS(status)) {
closeTcpFile( tcpFile );
return 0;
}
for( i = 0; i < numEntities; i++ ) {
if( isIpEntity( tcpFile, &entitySet[i] ) ) {
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) ) {
tdiFreeThingSet( entitySet );
closeTcpFile( tcpFile );
return status;
memset(&isnmp, 0, sizeof(isnmp));
status = tdiGetMibForIpEntity(tcpFile, &entitySet[i], &isnmp);
if (!NT_SUCCESS(status)) {
numRoutes = 0;
break;
}
numRoutes += isnmp.ipsi_numroutes;
}
}
TRACE("numRoutes: %d\n", (int)numRoutes);
tdiFreeThingSet( entitySet );
closeTcpFile( tcpFile );
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 );
NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA);
int i;
if( !NT_SUCCESS(status) )
if (!NT_SUCCESS(status))
return 0;
TRACE("GETTING ROUTE TABLE\n");
out_route_table = HeapAlloc( GetProcessHeap(), 0,
sizeof(RouteTable) +
(sizeof(RouteEntry) * (numRoutes - 1)) );
out_route_table = HeapAlloc(GetProcessHeap(), 0,
sizeof(RouteTable) +
(sizeof(RouteEntry) * (numRoutes - 1)));
if (!out_route_table) {
closeTcpFile(tcpFile);
return NULL;
@ -440,28 +372,20 @@ RouteTable *getRouteTable(void)
out_route_table->numRoutes = numRoutes;
for( i = 0; routesAdded < out_route_table->numRoutes; i++ ) {
for (i = 0; routesAdded < out_route_table->numRoutes; i++) {
int j;
IPRouteEntry *route_set;
getNthIpEntity( tcpFile, i, &ent );
getNthIpEntity(tcpFile, i, &ent);
tdiGetRoutesForIpEntity( tcpFile, &ent, &route_set, &numRoutes );
if( !route_set ) {
closeTcpFile( tcpFile );
HeapFree( GetProcessHeap(), 0, out_route_table );
tdiGetRoutesForIpEntity(tcpFile, &ent, &route_set, &numRoutes);
if (!route_set) {
closeTcpFile(tcpFile);
HeapFree(GetProcessHeap(), 0, out_route_table);
return 0;
}
TRACE( "%d routes in instance %d\n", numRoutes, i );
#if 0
HexDump( route_set,
sizeof( IPRouteEntry ) *
snmpInfo.ipsi_numroutes );
#endif
for( j = 0; j < numRoutes; j++ ) {
for (j = 0; j < numRoutes; j++) {
int routeNum = j + routesAdded;
out_route_table->routes[routeNum].dest =
route_set[j].ire_dest;
@ -475,15 +399,12 @@ RouteTable *getRouteTable(void)
route_set[j].ire_metric1;
}
if( route_set ) tdiFreeThingSet( route_set );
if (route_set) tdiFreeThingSet(route_set);
routesAdded += numRoutes;
}
closeTcpFile( tcpFile );
TRACE("Return: %08x, %08x\n", status, out_route_table);
closeTcpFile(tcpFile);
return out_route_table;
}
@ -497,43 +418,36 @@ DWORD getNumArpEntries(void)
PMIB_IPNETROW IpArpTable = NULL;
DWORD returnSize;
TRACE("called.\n");
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
TRACE("failure: %08x\n", (int)status );
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(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;
}
}
}
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( IpArpTable ) tdiFreeThingSet( IpArpTable );
if( entitySet ) tdiFreeThingSet( entitySet );
closeTcpFile(tcpFile);
if (entitySet) tdiFreeThingSet(entitySet);
return totalNumber;
}
@ -547,116 +461,256 @@ PMIB_IPNETTABLE getArpTable(void)
PMIB_IPNETTABLE IpArpTable = NULL;
PMIB_IPNETROW AdapterArpTable = NULL;
TRACE("called.\n");
totalNumber = getNumArpEntries();
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
TRACE("failure: %08x\n", (int)status );
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(status))
return 0;
}
IpArpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber) );
IpArpTable = HeapAlloc(GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber));
if (!IpArpTable) {
closeTcpFile(tcpFile);
return NULL;
}
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
for( i = 0; i < numEntities; i++ ) {
if( isInterface( &entitySet[i] ) &&
hasArp( tcpFile, &entitySet[i] ) ) {
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);
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++ )
if (status == STATUS_SUCCESS) {
for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++)
IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx];
tdiFreeThingSet( AdapterArpTable );
tdiFreeThingSet(AdapterArpTable);
}
}
}
closeTcpFile( tcpFile );
tdiFreeThingSet( entitySet );
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)
{
return getNumWithOneHeader("/proc/net/udp");
DWORD numEntities;
TDIEntityID *entitySet = NULL;
HANDLE tcpFile;
int i, totalNumber = 0;
NTSTATUS status;
PMIB_UDPROW IpUdpTable = NULL;
DWORD returnSize;
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(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;
}
PMIB_UDPTABLE getUdpTable(void)
PVOID getUdpTable(CLASS_TABLE Class)
{
DWORD numEntries = getNumUdpEntries();
PMIB_UDPTABLE ret;
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
HANDLE tcpFile;
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_UDPTABLE IpUdpTable = NULL;
PVOID AdapterUdpTable = NULL;
ret = (PMIB_UDPTABLE)calloc(1, sizeof(MIB_UDPTABLE) +
(numEntries - 1) * sizeof(MIB_UDPROW));
if (ret) {
FILE *fp;
totalNumber = getNumUdpEntries();
/* get from /proc/net/udp, no error if can't */
fp = fopen("/proc/net/udp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(status))
return 0;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
ret->dwNumEntries++;
}
}
fclose(fp);
IpUdpTable = HeapAlloc(GetProcessHeap(), 0,
UdpTcpTableCall[Class].UdpOffset + (UdpTcpTableCall[Class].UdpSize * totalNumber));
if (!IpUdpTable) {
closeTcpFile(tcpFile);
return NULL;
}
}
return ret;
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)
{
return getNumWithOneHeader("/proc/net/tcp");
DWORD numEntities;
TDIEntityID *entitySet = NULL;
HANDLE tcpFile;
int i, totalNumber = 0;
NTSTATUS status;
PMIB_TCPROW IpTcpTable = NULL;
DWORD returnSize;
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(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;
}
PMIB_TCPTABLE getTcpTable(void)
PVOID getTcpTable(CLASS_TABLE Class)
{
return 0;
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
HANDLE tcpFile;
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_TCPTABLE IpTcpTable = NULL;
PVOID AdapterTcpTable = NULL;
totalNumber = getNumTcpEntries();
status = openTcpFile(&tcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(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;
}

View file

@ -8,6 +8,10 @@
#pragma once
#include <tcpioctl.h>
#define DWORD ULONG
#include <in6addr.h>
#include <tcpmib.h>
#include <udpmib.h>
#define MAX_PHYSADDR_LEN 8
#define MAX_IFDESCR_LEN 256
@ -109,6 +113,16 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF,
PNDIS_BUFFER Buffer,
PUINT BufferSize );
TDI_STATUS InfoTdiQueryGetConnectionTcpTable(PADDRESS_FILE AddrFile,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
BOOLEAN Extended);
TDI_STATUS InfoTdiQueryGetConnectionUdpTable(PADDRESS_FILE AddrFile,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
BOOLEAN Extended);
TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF,
PVOID Buffer,
UINT BufferSize);

View file

@ -216,3 +216,5 @@ VOID CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const B
void
LibTCPDumpPcb(PVOID SocketContext);
NTSTATUS TCPGetSocketStatus(PCONNECTION_ENDPOINT Connection, PULONG State);

View file

@ -154,6 +154,7 @@ typedef struct _ADDRESS_FILE {
/* Associated listener (see transport/tcp/accept.c) */
IP_ADDRESS AddrCache; /* One entry address cache (destination
address of last packet transmitted) */
HANDLE ProcessId;
/* The following members are used to control event notification */
@ -272,7 +273,7 @@ typedef struct _CONNECTION_ENDPOINT {
LIST_ENTRY ShutdownRequest;/* Queued shutdown requests */
LIST_ENTRY PacketQueue; /* Queued received packets waiting to be processed */
/* Disconnect Timer */
KTIMER DisconnectTimer;
KDPC DisconnectDpc;

View file

@ -58,8 +58,6 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID,
return TDI_SUCCESS;
default:
DbgPrint("Unimplemented option %x\n", ID->toi_id);
return TDI_INVALID_REQUEST;
}
}

View file

@ -38,7 +38,7 @@ PADDRESS_FILE AddrSearchFirst(
PAF_SEARCH SearchContext)
{
KIRQL OldIrql;
SearchContext->Address = Address;
SearchContext->Port = Port;
SearchContext->Protocol = Protocol;
@ -111,7 +111,7 @@ LogActiveObjects(VOID)
PCONNECTION_ENDPOINT Conn;
DbgPrint("----------- TCP/IP Active Object Dump -------------\n");
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
CurrentEntry = AddressFileListHead.Flink;
@ -140,19 +140,19 @@ LogActiveObjects(VOID)
}
DbgPrint("\n");
}
CurrentEntry = CurrentEntry->Flink;
}
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
CurrentEntry = ConnectionEndpointListHead.Flink;
while (CurrentEntry != &ConnectionEndpointListHead)
{
Conn = CONTAINING_RECORD(CurrentEntry, CONNECTION_ENDPOINT, ListEntry);
DbgPrint("Connection @ 0x%p | Ref count: %d\n", Conn, Conn->RefCount);
DbgPrint("\tPCB: ");
if (Conn->SocketContext == NULL)
@ -173,10 +173,10 @@ LogActiveObjects(VOID)
DbgPrint("\tReceive shutdown: %s\n", Conn->ReceiveShutdown ? "Yes" : "No");
if (Conn->ReceiveShutdown) DbgPrint("\tReceive shutdown status: 0x%x\n", Conn->ReceiveShutdownStatus);
DbgPrint("\tClosing: %s\n", Conn->Closing ? "Yes" : "No");
CurrentEntry = CurrentEntry->Flink;
}
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
DbgPrint("---------------------------------------------------\n");
@ -233,7 +233,7 @@ PADDRESS_FILE AddrSearchNext(
PADDRESS_FILE Current = NULL;
BOOLEAN Found = FALSE;
PADDRESS_FILE StartingAddrFile;
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
if (SearchContext->Next == &AddressFileListHead)
@ -252,14 +252,6 @@ PADDRESS_FILE AddrSearchNext(
IPAddress = &Current->Address;
TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, %s), (%d, %d, %s)).\n",
WN2H(Current->Port),
Current->Protocol,
A2S(IPAddress),
WN2H(SearchContext->Port),
SearchContext->Protocol,
A2S(SearchContext->Address)));
/* See if this address matches the search criteria */
if ((Current->Port == SearchContext->Port) &&
(Current->Protocol == SearchContext->Protocol) &&
@ -309,8 +301,6 @@ VOID AddrFileFree(
PDATAGRAM_SEND_REQUEST SendRequest;
PLIST_ENTRY CurrentEntry;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* We should not be associated with a connection here */
ASSERT(!AddrFile->Connection);
@ -323,8 +313,6 @@ VOID AddrFileFree(
/* Return pending requests with error */
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
/* Go through pending receive request list and cancel them all */
while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
@ -332,8 +320,6 @@ VOID AddrFileFree(
/* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
/* Go through pending send request list and cancel them all */
while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
@ -393,8 +379,6 @@ NTSTATUS FileOpenAddress(
{
PADDRESS_FILE AddrFile;
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
/* If it's shared and has a port specified, look for a match */
if ((Shared != FALSE) && (Address->Address[0].Address[0].sin_port != 0))
{
@ -424,6 +408,7 @@ NTSTATUS FileOpenAddress(
AddrFile->DF = 0;
AddrFile->BCast = 1;
AddrFile->HeaderIncl = 1;
AddrFile->ProcessId = PsGetCurrentProcessId();
/* Make sure address is a local unicast address or 0 */
/* FIXME: IPv4 only */
@ -438,9 +423,6 @@ NTSTATUS FileOpenAddress(
return STATUS_INVALID_ADDRESS;
}
TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n",
A2S(&AddrFile->Address), Protocol, IPPROTO_UDP));
/* Protocol specific handling */
switch (Protocol) {
case IPPROTO_TCP:
@ -448,14 +430,14 @@ NTSTATUS FileOpenAddress(
{
/* The client specified an explicit port so we force a bind to this */
AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port);
/* Check for bind success */
if (AddrFile->Port == 0xffff)
{
ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
return STATUS_ADDRESS_ALREADY_EXISTS;
}
/* Sanity check */
ASSERT(Address->Address[0].Address[0].sin_port == AddrFile->Port);
}
@ -463,7 +445,7 @@ NTSTATUS FileOpenAddress(
{
/* The client is trying to bind to a local address so allocate a port now too */
AddrFile->Port = TCPAllocatePort(0);
/* Check for bind success */
if (AddrFile->Port == 0xffff)
{
@ -483,7 +465,6 @@ NTSTATUS FileOpenAddress(
break;
case IPPROTO_UDP:
TI_DbgPrint(MID_TRACE,("Allocating udp port\n"));
AddrFile->Port =
UDPAllocatePort(Address->Address[0].Address[0].sin_port);
@ -495,10 +476,6 @@ NTSTATUS FileOpenAddress(
return STATUS_ADDRESS_ALREADY_EXISTS;
}
TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n",
AddrFile->Port,
Address->Address[0].Address[0].sin_port));
AddEntity(CL_TL_ENTITY, AddrFile, CL_TL_UDP);
AddrFile->Send = UDPSendDatagram;
@ -522,12 +499,6 @@ NTSTATUS FileOpenAddress(
break;
}
TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
Protocol));
TI_DbgPrint(MID_TRACE, ("Port number for address file object is %d.\n",
WN2H(AddrFile->Port)));
/* Set protocol */
AddrFile->Protocol = Protocol;
@ -547,8 +518,6 @@ NTSTATUS FileOpenAddress(
&AddrFile->ListEntry,
&AddressFileListLock);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}
@ -587,8 +556,6 @@ NTSTATUS FileCloseAddress(
DereferenceObject(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}
@ -608,8 +575,6 @@ NTSTATUS FileOpenConnection(
NTSTATUS Status;
PCONNECTION_ENDPOINT Connection;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Connection = TCPAllocateConnectionEndpoint( ClientContext );
if( !Connection ) return STATUS_NO_MEMORY;
@ -624,8 +589,6 @@ NTSTATUS FileOpenConnection(
/* Return connection endpoint file object */
Request->Handle.ConnectionContext = Connection;
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}
@ -641,8 +604,6 @@ NTSTATUS FileCloseConnection(
{
PCONNECTION_ENDPOINT Connection;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Connection = Request->Handle.ConnectionContext;
if (!Connection) return STATUS_INVALID_PARAMETER;
@ -651,8 +612,6 @@ NTSTATUS FileCloseConnection(
Request->Handle.ConnectionContext = NULL;
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}
@ -667,7 +626,6 @@ NTSTATUS FileOpenControlChannel(
PTDI_REQUEST Request)
{
PCONTROL_CHANNEL ControlChannel;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
ControlChannel = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ControlChannel),
CONTROL_CHANNEL_TAG);
@ -695,8 +653,6 @@ NTSTATUS FileOpenControlChannel(
/* Return address file object */
Request->Handle.ControlChannel = ControlChannel;
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}

View file

@ -83,7 +83,6 @@ PVOID GetContext(TDIEntityID ID)
if (i == EntityCount)
{
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
DbgPrint("WARNING: Unable to get context for %d %d\n", ID.tei_entity, ID.tei_instance);
return NULL;
}
@ -260,14 +259,24 @@ TDI_STATUS InfoTdiQueryInformationEx(
return TDI_INVALID_PARAMETER;
case IP_MIB_ADDRTABLE_ENTRY_ID:
if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
ID->toi_entity.tei_entity != CO_NL_ENTITY)
return TDI_INVALID_PARAMETER;
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
return InfoTdiQueryGetAddrTable(ID->toi_entity, Buffer, BufferSize);
if (ID->toi_entity.tei_entity == CL_NL_ENTITY ||
ID->toi_entity.tei_entity == CO_NL_ENTITY)
return InfoTdiQueryGetAddrTable(ID->toi_entity, Buffer, BufferSize);
else if (ID->toi_entity.tei_entity == CO_TL_ENTITY)
if ((EntityListContext = GetContext(ID->toi_entity)))
return InfoTdiQueryGetConnectionTcpTable(EntityListContext, Buffer, BufferSize, TRUE);
else
return TDI_INVALID_PARAMETER;
else if (ID->toi_entity.tei_entity == CL_TL_ENTITY)
if ((EntityListContext = GetContext(ID->toi_entity)))
return InfoTdiQueryGetConnectionUdpTable(EntityListContext, Buffer, BufferSize, TRUE);
else
return TDI_INVALID_PARAMETER;
else
return TDI_INVALID_PARAMETER;
case IP_MIB_ARPTABLE_ENTRY_ID:
if (ID->toi_type != INFO_TYPE_PROVIDER)
@ -285,6 +294,16 @@ TDI_STATUS InfoTdiQueryInformationEx(
return InfoTdiQueryGetRouteTable(EntityListContext, Buffer, BufferSize);
else
return TDI_INVALID_PARAMETER;
else if (ID->toi_entity.tei_entity == CO_TL_ENTITY)
if ((EntityListContext = GetContext(ID->toi_entity)))
return InfoTdiQueryGetConnectionTcpTable(EntityListContext, Buffer, BufferSize, FALSE);
else
return TDI_INVALID_PARAMETER;
else if (ID->toi_entity.tei_entity == CL_TL_ENTITY)
if ((EntityListContext = GetContext(ID->toi_entity)))
return InfoTdiQueryGetConnectionUdpTable(EntityListContext, Buffer, BufferSize, FALSE);
else
return TDI_INVALID_PARAMETER;
else
return TDI_INVALID_PARAMETER;
@ -371,13 +390,11 @@ TDI_STATUS InfoTdiSetInformationEx
}
}
default:
DbgPrint("TCPIP: IOCTL_TCP_SET_INFORMATION_EX - Unrecognized information type for INFO_CLASS_PROTOCOL: %#x.\n", ID->toi_type);
return TDI_INVALID_PARAMETER;
}
break;
}
default:
DbgPrint("TCPIP: IOCTL_TCP_SET_INFORMATION_EX - Unrecognized information class %#x.\n", ID->toi_class);
return TDI_INVALID_REQUEST;
}
}

View file

@ -23,9 +23,6 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI
PIPROUTE_ENTRY RouteEntries, RtCurrent;
UINT i;
TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d\n",
RtCount));
if (RtCount == 0)
return InfoCopyOut(NULL, 0, NULL, BufferSize);
@ -47,7 +44,6 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI
while( RtCurrent < RouteEntries + RtCount ) {
ASSERT(RCacheCur->Router);
RtlCopyMemory( &RtCurrent->Dest,
&RCacheCur->NetworkAddress.Address,
sizeof(RtCurrent->Dest) );
@ -61,15 +57,6 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI
RtCurrent->Metric1 = RCacheCur->Metric;
RtCurrent->Type = TDI_ADDRESS_TYPE_IP;
TI_DbgPrint
(DEBUG_INFO,
("%d: NA %08x NM %08x GW %08x MT %x\n",
RtCurrent - RouteEntries,
RtCurrent->Dest,
RtCurrent->Mask,
RtCurrent->Gw,
RtCurrent->Metric1 ));
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
for (i = 0; i < EntityCount; i++)
if (EntityList[i].context == IF)
@ -90,8 +77,6 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI
ExFreePoolWithTag( RouteEntries, ROUTE_ENTRY_TAG );
ExFreePoolWithTag( RCache, FIB_TAG );
TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
return Status;
}
@ -104,9 +89,6 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID,
PIP_INTERFACE CurrentIF;
UINT i;
TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
for (i = 0; i < EntityCount; i++)
@ -161,8 +143,6 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID,
UINT RouteCount = CountFIBs(IF);
TDI_STATUS Status = TDI_INVALID_REQUEST;
TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
RtlZeroMemory(&SnmpInfo, sizeof(SnmpInfo));
SnmpInfo.ipsi_numif = IfCount;
@ -172,7 +152,80 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID,
Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo),
Buffer, BufferSize );
TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
return Status;
}
#define ntohs(n) ((((n) & 0xff) << 8) | (((n) & 0xff00) >> 8))
TDI_STATUS InfoTdiQueryGetConnectionTcpTable(PADDRESS_FILE AddrFile,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
BOOLEAN Extended)
{
SIZE_T Size;
MIB_TCPROW_OWNER_PID TcpRow;
TDI_STATUS Status = TDI_INVALID_REQUEST;
TcpRow.dwOwningPid = HandleToUlong(AddrFile->ProcessId);
if (Extended)
Size = sizeof(MIB_TCPROW_OWNER_PID);
else
Size = sizeof(MIB_TCPROW);
if (AddrFile->Listener)
{
PADDRESS_FILE EndPoint;
EndPoint = AddrFile->Listener->AddressFile;
TcpRow.dwState = MIB_TCP_STATE_LISTEN;
TcpRow.dwLocalAddr = AddrFile->Address.Address.IPv4Address;
TcpRow.dwLocalPort = AddrFile->Port;
TcpRow.dwRemoteAddr = EndPoint->Address.Address.IPv4Address;
TcpRow.dwRemotePort = EndPoint->Port;
Status = TDI_SUCCESS;
}
else if (AddrFile->Connection && AddrFile->Connection->SocketContext)
{
TA_IP_ADDRESS EndPoint;
Status = TCPGetSockAddress(AddrFile->Connection, (PTRANSPORT_ADDRESS)&EndPoint, FALSE);
if (NT_SUCCESS(Status))
{
TcpRow.dwLocalAddr = EndPoint.Address[0].Address[0].in_addr;
TcpRow.dwLocalPort = ntohs(EndPoint.Address[0].Address[0].sin_port);
Status = TCPGetSockAddress(AddrFile->Connection, (PTRANSPORT_ADDRESS)&EndPoint, TRUE);
if (NT_SUCCESS(Status))
{
TcpRow.dwRemoteAddr = EndPoint.Address[0].Address[0].in_addr;
TcpRow.dwRemotePort = ntohs(EndPoint.Address[0].Address[0].sin_port);
Status = TCPGetSocketStatus(AddrFile->Connection, &TcpRow.dwState);
}
}
}
if (NT_SUCCESS(Status))
Status = InfoCopyOut((PCHAR)&TcpRow, Size, Buffer, BufferSize);
return Status;
}
TDI_STATUS InfoTdiQueryGetConnectionUdpTable(PADDRESS_FILE AddrFile,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
BOOLEAN Extended)
{
MIB_UDPROW_OWNER_PID UdpRow;
TDI_STATUS Status = TDI_INVALID_REQUEST;
UdpRow.dwLocalAddr = AddrFile->Address.Address.IPv4Address;
UdpRow.dwLocalPort = AddrFile->Port;
UdpRow.dwOwningPid = HandleToUlong(AddrFile->ProcessId);
Status = InfoCopyOut((PCHAR)&UdpRow, (Extended ? sizeof(MIB_UDPROW_OWNER_PID) : sizeof(MIB_UDPROW)), Buffer, BufferSize);
return Status;
}
@ -190,20 +243,15 @@ TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize)
return TDI_INVALID_PARAMETER;
if (IF == Loopback)
{
DbgPrint("Failing attempt to add route to loopback adapter\n");
return TDI_INVALID_PARAMETER;
}
if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
if (!RouterCreateRoute( &Address, &Netmask, &Router,
IF, Route->Metric1))
return TDI_NO_RESOURCES;
return TDI_SUCCESS;
} else if( Route->Type == IP_ROUTE_TYPE_DEL ) {
TI_DbgPrint(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address)));
if (NT_SUCCESS(RouterRemoveRoute( &Address, &Router )))
return TDI_SUCCESS;
else

View file

@ -27,6 +27,7 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO,PULONG);
DWORD WINAPI GetBestInterface(IPAddr,PDWORD);
DWORD WINAPI GetBestRoute(DWORD,DWORD,PMIB_IPFORWARDROW);
DWORD WINAPI GetExtendedTcpTable(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
DWORD WINAPI GetExtendedUdpTable(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG);
DWORD WINAPI GetFriendlyIfIndex(DWORD);
DWORD WINAPI GetIcmpStatistics(PMIB_ICMP);
DWORD WINAPI GetIfEntry(PMIB_IFROW);

View file

@ -51,6 +51,10 @@
#define IP_MIB_ARPTABLE_ENTRY_ID 0x101
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
#define IP_INTFC_INFO_ID 0x103
/* Non public TOIID used to query modules info */
#ifdef __REACTOS__
#define IP_SPECIFIC_MODULE_ENTRY_ID 0x110
#endif
#define MAX_PHYSADDR_SIZE 8
/* Address Object Options */

View file

@ -43,29 +43,29 @@ DisconnectTimeoutDpc(PKDPC Dpc,
while (!IsListEmpty(&Connection->SendRequest))
{
Entry = RemoveHeadList(&Connection->SendRequest);
Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
Bucket->Information = 0;
Bucket->Status = STATUS_FILE_CLOSED;
CompleteBucket(Connection, Bucket, FALSE);
}
while (!IsListEmpty(&Connection->ShutdownRequest))
{
Entry = RemoveHeadList( &Connection->ShutdownRequest );
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Bucket->Status = STATUS_TIMEOUT;
Bucket->Information = 0;
CompleteBucket(Connection, Bucket, FALSE);
}
UnlockObjectFromDpcLevel(Connection);
DereferenceObject(Connection);
}
@ -176,7 +176,7 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to lwIP\n",
IPPacket->TotalSize,
IPPacket->HeaderSize));
LibIPInsertPacket(Interface->TCPContext, IPPacket->Header, IPPacket->TotalSize);
}
@ -202,13 +202,13 @@ NTSTATUS TCPStartup(VOID)
sizeof(TDI_BUCKET),
TDI_BUCKET_TAG,
0);
/* Initialize our IP library */
LibIPInitialize();
/* Register this protocol with IP layer */
IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
TCPInitialized = TRUE;
return STATUS_SUCCESS;
@ -226,7 +226,7 @@ NTSTATUS TCPShutdown(VOID)
return STATUS_SUCCESS;
ExDeleteNPagedLookasideList(&TdiBucketLookasideList);
LibIPShutdown();
/* Deregister this protocol with IP layer */
@ -334,7 +334,7 @@ NTSTATUS TCPConnect
Status = TCPTranslateError(LibTCPBind(Connection,
&bindaddr,
Connection->AddressFile->Port));
if (NT_SUCCESS(Status))
{
/* Copy bind address into connection */
@ -348,7 +348,7 @@ NTSTATUS TCPConnect
{
/* Allocate the port in the port bitmap */
Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port);
/* This should never fail */
ASSERT(Connection->AddressFile->Port != 0xFFFF);
}
@ -364,12 +364,12 @@ NTSTATUS TCPConnect
UnlockObject(Connection, OldIrql);
return STATUS_NO_MEMORY;
}
Bucket->Request.RequestNotifyObject = (PVOID)Complete;
Bucket->Request.RequestContext = Context;
InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
Status = TCPTranslateError(LibTCPConnect(Connection,
&connaddr,
RemotePort));
@ -415,7 +415,7 @@ NTSTATUS TCPDisconnect
TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
Status = STATUS_TIMEOUT;
}
else
else
{
/* Use the timeout specified or 1 second if none was specified */
if (Timeout)
@ -502,7 +502,7 @@ NTSTATUS TCPReceiveData
return STATUS_NO_MEMORY;
}
Bucket->Request.RequestNotifyObject = Complete;
Bucket->Request.RequestContext = Context;
@ -548,7 +548,7 @@ NTSTATUS TCPSendData
SendLength,
BytesSent,
FALSE));
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength));
/* Keep this request around ... there was no data yet */
@ -562,10 +562,10 @@ NTSTATUS TCPSendData
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Failed to allocate bucket\n"));
return STATUS_NO_MEMORY;
}
Bucket->Request.RequestNotifyObject = Complete;
Bucket->Request.RequestContext = Context;
InsertTailList( &Connection->SendRequest, &Bucket->Entry );
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n"));
}
@ -607,7 +607,7 @@ NTSTATUS TCPGetSockAddress
struct ip_addr ipaddr;
NTSTATUS Status;
KIRQL OldIrql;
AddressIP->TAAddressCount = 1;
AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
@ -628,9 +628,9 @@ NTSTATUS TCPGetSockAddress
}
UnlockObject(Connection, OldIrql);
AddressIP->Address[0].Address[0].in_addr = ipaddr.addr;
RtlZeroMemory(&AddressIP->Address[0].Address[0].sin_zero,
sizeof(AddressIP->Address[0].Address[0].sin_zero));
@ -691,5 +691,19 @@ TCPSetNoDelay(
return STATUS_SUCCESS;
}
NTSTATUS
TCPGetSocketStatus(
PCONNECTION_ENDPOINT Connection,
PULONG State)
{
if (!Connection)
return STATUS_UNSUCCESSFUL;
if (Connection->SocketContext == NULL)
return STATUS_UNSUCCESSFUL;
LibTCPGetSocketStatus(Connection->SocketContext, State);
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -25,7 +25,7 @@ struct lwip_callback_msg
{
/* Synchronization */
KEVENT Event;
/* Input */
union {
struct {
@ -60,7 +60,7 @@ struct lwip_callback_msg
int Callback;
} Close;
} Input;
/* Output */
union {
struct {
@ -110,6 +110,7 @@ err_t LibTCPGetPeerName(PTCP_PCB pcb, struct ip_addr *const ipaddr, u16_t
err_t LibTCPGetHostName(PTCP_PCB pcb, struct ip_addr *const ipaddr, u16_t *const port);
void LibTCPAccept(PTCP_PCB pcb, struct tcp_pcb *listen_pcb, void *arg);
void LibTCPSetNoDelay(PTCP_PCB pcb, BOOLEAN Set);
void LibTCPGetSocketStatus(PTCP_PCB pcb, PULONG State);
/* IP functions */
void LibIPInsertPacket(void *ifarg, const void *const data, const u32_t size);

View file

@ -840,3 +840,11 @@ LibTCPSetNoDelay(
else
pcb->flags &= ~TF_NODELAY;
}
void
LibTCPGetSocketStatus(
PTCP_PCB pcb,
PULONG State)
{
*State = pcb->state + 1;
}