Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1458 lines
42 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
Abstract:
Revision History:
Amritansh Raghav
--*/
#include "allinc.h"
//
// Definitions
//
//*****************************************************************************
//
// Name: GetIpAddrTableFromStack
//
// Description:
//
// Parameters: IPAddrEntry *lpipaeTable, LPDWORD lpdwNumEntries, BOOL bOrder
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetIpAddrTableFromStack(IPAddrEntry *lpipaeTable, LPDWORD lpdwNumEntries,
BOOL bOrder, BOOL bMap)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
DWORD i,j;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TraceEnter("GetIpAddrTableFromStack");
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = (*lpdwNumEntries) * sizeof( IPAddrEntry );
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_NL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = IP_MIB_ADDRTABLE_ENTRY_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)lpipaeTable,
&dwOutBufLen );
if (dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetIpAddrTableFromStack: NtStatus %x querying IpAddrTable from stack",
dwResult);
TraceLeave("GetIpAddrTableFromStack");
return dwResult;
}
*lpdwNumEntries =(dwOutBufLen / sizeof(IPAddrEntry));
//
// Now sort the address table. Key is IP address.
//
if(*lpdwNumEntries > 0)
{
if(bMap)
{
for (i = 0; i < (*lpdwNumEntries); i++ )
{
lpipaeTable[i].iae_index = GetInterfaceFromAdapter(lpipaeTable[i].iae_index);
}
}
if(bOrder)
{
for (i = 0; i < (*lpdwNumEntries) - 1; i++ )
{
IPAddrEntry tempEntry;
DWORD min;
LONG lCompare;
min = i;
for (j = i + 1; j < *lpdwNumEntries; j++ )
{
if(InetCmp(lpipaeTable[min].iae_addr,lpipaeTable[j].iae_addr,lCompare) > 0)
{
min = j;
}
}
if(min isnot i)
{
tempEntry = lpipaeTable[min];
lpipaeTable[min] = lpipaeTable[i];
lpipaeTable[i] = tempEntry;
}
}
}
}
TraceLeave("GetIpAddrTableFromStack");
return NO_ERROR;
}
//*****************************************************************************
//
// Name: GetTcpConnTableFromStack
//
// Description: Reads and sorts the route table from the stack.
//
// Parameters: TCPConnTableEntry *lptcteTable, LPDWORD lpdwNumEntries, BOOL bOrder
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetTcpTableFromStack(TCPConnTableEntry *lptcteTable, LPDWORD lpdwNumEntries, BOOL bOrder)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
DWORD i,j;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TCPStats TcpInfo;
DWORD NumConn;
DWORD *IndTab;
LONG CmpResult;
TraceEnter("GetTcpTableFromStack");
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = (*lpdwNumEntries) * sizeof(TCPConnTableEntry);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CO_TL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = TCP_MIB_TABLE_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)lptcteTable,
&dwOutBufLen);
if (dwResult isnot NO_ERROR )
{
Trace1(ERR,
"GetTcpTableFromStack: NtStatus %x querying TcpConnTable from stack",
dwResult);
TraceLeave("GetTcpTableFromStack");
return dwResult;
}
*lpdwNumEntries = (dwOutBufLen/sizeof(TCPConnTableEntry));
//
// Now sort the TCP connection table. Keys are: local address, local
// port, remote address, and remote port.
//
if((*lpdwNumEntries > 0) and bOrder)
{
for ( i = 0; i < (*lpdwNumEntries) - 1 ; i++ )
{
TCPConnTableEntry tempEntry;
DWORD min;
min = i;
for ( j = i+1; j < *lpdwNumEntries ; j++ )
{
if(TcpCmp(lptcteTable[min].tct_localaddr,lptcteTable[min].tct_localport,
lptcteTable[min].tct_remoteaddr,lptcteTable[min].tct_remoteport,
lptcteTable[j].tct_localaddr,lptcteTable[j].tct_localport,
lptcteTable[j].tct_remoteaddr,lptcteTable[j].tct_remoteport) > 0)
{
min = j;
}
}
if(min isnot i)
{
tempEntry = lptcteTable[min];
lptcteTable[min] = lptcteTable[i];
lptcteTable[i] = tempEntry;
}
}
}
TraceLeave("GetTcpTableFromStack");
return NO_ERROR;
}
DWORD
SetTcpRowToStack(TCPConnTableEntry *tcpRow)
{
TCP_REQUEST_SET_INFORMATION_EX *lptrsiInBuf;
TDIObjectID *ID;
UCHAR *Context;
TCPConnTableEntry *copyInfo;
DWORD dwInBufLen,dwOutBufLen,dwResult;
TraceEnter("SetTcpRowToStack");
dwInBufLen = sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(TCPConnTableEntry) - 1;
lptrsiInBuf = HeapAlloc(GetProcessHeap(),0,dwInBufLen);
if(lptrsiInBuf is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"SetTcpRowToStack: Error %d allocating memory",
dwResult);
TraceLeave("SetTcpRowToStack");
return dwResult;
}
ID = &lptrsiInBuf->ID;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_entity.tei_entity = CO_TL_ENTITY;
ID->toi_id = TCP_MIB_TABLE_ID;
ID->toi_entity.tei_instance = 0;
lptrsiInBuf->BufferSize = sizeof(TCPConnTableEntry);
copyInfo = (TCPConnTableEntry*)lptrsiInBuf->Buffer;
*copyInfo = *tcpRow;
dwResult = TCPSetInformationEx(g_hTcpDevice,
(LPVOID)lptrsiInBuf,
&dwInBufLen,
NULL,
&dwOutBufLen);
HeapFree(GetProcessHeap(),0,lptrsiInBuf);
TraceLeave("SetTcpRowToStack");
return dwResult;
}
//*****************************************************************************
//
// Name: GetUdpConnTableFromStack
//
// Description: Reads and sorts the route table from the stack.
//
// Parameters: UDPEntry *lpueTable, LPDWORD lpdwNumEntries, BOOL bOrder
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetUdpTableFromStack(UDPEntry *lpueTable, LPDWORD lpdwNumEntries, BOOL bOrder)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
DWORD i,j;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TraceEnter("GetUdpTableFromStack");
//
// Determine number of connections via the UDPStats structure
//
dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
dwOutBufLen = (*lpdwNumEntries) * sizeof(UDPEntry);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_TL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = UDP_MIB_TABLE_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)lpueTable,
&dwOutBufLen );
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetUdpTableFromStack: NtStatus %x querying UdpTable from stack",
dwResult);
TraceLeave("GetUdpTableFromStack");
return dwResult;
}
*lpdwNumEntries =(dwOutBufLen / sizeof(UDPEntry));
//
// Now sort the UDP connection table. Keys are: local address, and local
// port.
//
if((*lpdwNumEntries > 0) and bOrder)
{
for ( i = 0; i < (*lpdwNumEntries) - 1; i++ )
{
UDPEntry tempEntry;
DWORD min;
min = i;
for ( j = i + 1; j < (*lpdwNumEntries) ; j++ )
{
if(UdpCmp(lpueTable[min].ue_localaddr,
lpueTable[min].ue_localport,
lpueTable[j].ue_localaddr,
lpueTable[j].ue_localport) > 0)
{
min = j;
}
}
if(min isnot i)
{
tempEntry = lpueTable[min];
lpueTable[min] = lpueTable[i];
lpueTable[i] = tempEntry;
}
}
}
TraceLeave("GetUdpTableFromStack");
return NO_ERROR;
}
//*****************************************************************************
//
// Name: GetIpStatsFromStack
//
// Description: Read the IPSNMPInfo structure from the stack.
//
// Parameters: IPSNMPInfo *IPSnmpInfo
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetIpStatsFromStack(IPSNMPInfo *IPSnmpInfo)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TraceEnter("GetIpStatsFromStack");
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = sizeof(IPSNMPInfo);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_NL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = IP_MIB_STATS_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory(Context, CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
IPSnmpInfo,
&dwOutBufLen);
if (dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetIpStatsFromStack: NtStatus %x querying IpStats from stack",
dwResult);
TraceLeave("GetIpStatsFromStack");
return dwResult;
}
TraceLeave("GetIpStatsFromStack");
return NO_ERROR;
}
DWORD
SetIpInfoToStack(IPSNMPInfo *ipsiInfo)
{
TCP_REQUEST_SET_INFORMATION_EX *lptrsiInBuf;
TDIObjectID *ID;
UCHAR *Context;
IPSNMPInfo *copyInfo;
DWORD dwInBufLen,dwOutBufLen,dwResult;
TraceEnter("SetIpInfoToStack");
dwInBufLen = sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(IPSNMPInfo) - 1;
lptrsiInBuf = HeapAlloc(GetProcessHeap(),0,dwInBufLen);
if(lptrsiInBuf is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"SetIpInfoToStack: Error %d allocating memory",
dwResult);
TraceLeave("SetIpInfoToStack");
return dwResult;
}
ID = &lptrsiInBuf->ID;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_entity.tei_entity = CL_NL_ENTITY;
ID->toi_id = IP_MIB_STATS_ID;
ID->toi_entity.tei_instance = 0;
copyInfo = (IPSNMPInfo*)lptrsiInBuf->Buffer;
*copyInfo = *ipsiInfo;
dwResult = TCPSetInformationEx(g_hTcpDevice,
(LPVOID)lptrsiInBuf,
&dwInBufLen,
NULL,
&dwOutBufLen);
TraceLeave("SetIpInfoToStack");
return dwResult;
}
//*****************************************************************************
//
// Name: GetIcmpStatsFromStack
//
// Description: Read the ICMPSNMPInfo structure from the stack.
//
// Parameters: ICMPSNMPInfo *ICMPSnmpInfo
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetIcmpStatsFromStack( ICMPSNMPInfo *ICMPSnmpInfo )
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TraceEnter("GetIcmpStatsFromStack");
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = sizeof(ICMPSNMPInfo);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = ER_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = ICMP_MIB_STATS_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory(Context,CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
ICMPSnmpInfo,
&dwOutBufLen );
if (dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetIcmpStatsFromStack: NtStatus %x querying IcmpStats from stack",
dwResult);
TraceLeave("GetIcmpStatsFromStack");
return dwResult;
}
TraceLeave("GetIcmpStatsFromStack");
return NO_ERROR;
}
//*****************************************************************************
//
// Name: GetUdpStatsFromStack
//
// Description: Read the UDPStats structure from the stack.
//
// Parameters: UDPStats *UdpInfo
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetUdpStatsFromStack(UDPStats *UdpInfo)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TraceEnter("GetUdpStatsFromStack");
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = sizeof(UDPStats);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_TL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = UDP_MIB_STAT_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
UdpInfo,
&dwOutBufLen );
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetUdpStatsFromStack: NtStatus %x querying UdpStats from stack",
dwResult);
TraceLeave("GetUdpStatsFromStack");
return dwResult;
}
TraceLeave("GetUdpStatsFromStack");
return NO_ERROR;
}
//*****************************************************************************
//
// Name: GetTCPStats
//
// Description: Read the TCPStats structure from the stack.
//
// Parameters:
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetTcpStatsFromStack(TCPStats *TcpInfo)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
BYTE *Context;
TraceEnter("GetTcpStatsFromStack");
dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
dwOutBufLen = sizeof( TCPStats );
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CO_TL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = TCP_MIB_STAT_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory(Context,CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
TcpInfo,
&dwOutBufLen );
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetTcpStatsFromStack: NtStatus %x querying TcpStats from stack",
dwResult);
TraceLeave("GetTcpStatsFromStack");
return dwResult;
}
TraceLeave("GetTcpStatsFromStack");
return NO_ERROR;
}
//*****************************************************************************
//
// Name: GetRouteTableFromStack
//
// Description: Reads all the routes from the stack. This is needed because the ICMP redirect
// routes are only kept in the stack and cant be queried from RTM
//
// Parameters:
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetIpRouteTableFromStack(IPRouteEntry *lpireTable,LPDWORD lpdwNumEntries, BOOL bOrder)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
UCHAR *Context;
TDIObjectID *ID;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
IPSNMPInfo ipsiInfo;
TraceEnter("GetIpRouteTableFromStack");
dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
dwOutBufLen = *lpdwNumEntries * sizeof(IPRouteEntry);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = CL_NL_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)lpireTable,
&dwOutBufLen );
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetIpRouteTableFromStack: NtStatus %x querying IpRouteTable from stack",
dwResult);
TraceLeave("GetIpRouteTableFromStack");
return dwResult;
}
*lpdwNumEntries = (dwOutBufLen / sizeof( IPRouteEntry ));
if((*lpdwNumEntries > 0) and bOrder)
{
DWORD i,j;
for (i = 0; i < (*lpdwNumEntries) - 1; i++ )
{
IPRouteEntry tempEntry;
DWORD min;
LONG lCompare;
min = i;
for (j = i + 1; j < *lpdwNumEntries; j++ )
{
if(InetCmp(lpireTable[min].ire_dest,lpireTable[j].ire_dest,lCompare) > 0)
{
min = j;
}
}
if(min isnot i)
{
tempEntry = lpireTable[min];
lpireTable[min] = lpireTable[i];
lpireTable[i] = tempEntry;
}
}
}
TraceLeave("GetIpRouteTableFromStack");
return NO_ERROR;
}
//*****************************************************************************
//
// Name: GetARPEntityTable
//
// Description: Builds a list of AT entities. that support ARP. Keeps it in the global
// entity table
//
// Parameters:
//
// Returns: DWORD: NO_ERROR or some error code.
//
// History:
//
//*****************************************************************************
DWORD
GetArpEntTableFromStack(DWORD **lpArpEntTable,
LPDWORD lpdwSize,
LPDWORD lpdwValid,
HANDLE hHeap)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
DWORD dwATType;
UCHAR *Context;
TDIObjectID *ID;
LPVOID lpOutBuf;
TDIEntityID *lpEntTable;
DWORD dwNumEntities;
DWORD i,dwCount ;
TraceEnter("GetArpEntTableFromStack");
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwOutBufLen = MAX_TDI_ENTITIES * sizeof(TDIEntityID);
lpOutBuf = HeapAlloc(GetProcessHeap(),0,dwOutBufLen);
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = GENERIC_ENTITY;
ID->toi_entity.tei_instance = 0;
ID->toi_class = INFO_CLASS_GENERIC;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = ENTITY_LIST_ID;
Context = &(trqiInBuf.Context[0]);
ZeroMemory(Context, CONTEXT_SIZE);
if(lpOutBuf is NULL)
{
dwResult = GetLastError();
Trace1(ERR,"GetArpEntTableFromStack: Error %d allocating memory",
dwResult);
TraceLeave("GetArpEntTableFromStack");
return dwResult;
}
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
lpOutBuf,
&dwOutBufLen);
if ( dwResult != NO_ERROR )
{
Trace1(ERR,
"GetArpEntTableFromStack: NtStatus %x querying TDI Entities from stack",
dwResult);
HeapFree(GetProcessHeap(),0,lpOutBuf);
TraceLeave("GetArpEntTableFromStack");
return dwResult;
}
//
// Now we have all the entities
//
dwNumEntities = dwOutBufLen / sizeof( TDIEntityID );
dwCount = 0;
lpEntTable = (TDIEntityID*)lpOutBuf;
for(i = 0; i < dwNumEntities; i++)
{
//
// See which ones are AT
//
if(lpEntTable[i].tei_entity is AT_ENTITY)
{
//
// Query the entity to see if it supports ARP
//
ID->toi_entity.tei_entity = AT_ENTITY;
ID->toi_class = INFO_CLASS_GENERIC;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = ENTITY_TYPE_ID;
ID->toi_entity.tei_instance = lpEntTable[i].tei_instance;
dwOutBufLen = sizeof(dwATType);
ZeroMemory(Context,CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)&dwATType,
&dwOutBufLen );
if(dwResult is STATUS_INVALID_DEVICE_REQUEST)
{
continue;
}
if(dwResult isnot NO_ERROR)
{
HeapFree(GetProcessHeap(),0,lpOutBuf);
return dwResult;
}
if(dwATType is AT_ARP)
{
if(dwCount is *lpdwSize)
{
//
// Realloc more memory
//
*lpArpEntTable = (LPDWORD)HeapReAlloc(hHeap,
0,
(LPVOID)*lpArpEntTable,
((*lpdwSize)<<1)*sizeof(DWORD));
if(*lpArpEntTable is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"GetArpEntTableFromStack: Error %d reallocating memory",
dwResult);
TraceLeave("GetArpEntTableFromStack");
return dwResult;
}
*lpdwSize = (*lpdwSize)<<1;
}
(*lpArpEntTable)[dwCount++] = lpEntTable[i].tei_instance;
}
}
}
*lpdwValid = dwCount;
HeapFree(GetProcessHeap(),0,lpOutBuf);
TraceLeave("GetArpEntTableFromStack");
return NO_ERROR;
}
// Called only if you are a IPNET reader
DWORD
UpdateAdapterToATInstanceMap()
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD i;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
UCHAR *Context;
DWORD dwSize;
AddrXlatInfo AXI;
TraceEnter("UpdateAdapterToATInstanceMap");
dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
Context = &(trqiInBuf.Context[0]);
ID = &(trqiInBuf.ID);
//
// Maybe we should first clear out all the mappings
//
for (i = 0; i < g_IpInfo.dwValidArpEntEntries; i++ )
{
ID->toi_entity.tei_entity = AT_ENTITY;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_id = AT_MIB_ADDRXLAT_INFO_ID;
ID->toi_entity.tei_instance = g_IpInfo.arpEntTable[i];
dwSize = sizeof(AXI);
ZeroMemory(Context, CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
&AXI,
&dwSize );
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"UpdateAdapterToATInstanceMap: NtStatus %x querying ArpInfo from stack",
dwResult);
TraceLeave("UpdateAdapterToATInstanceMap");
return dwResult;
}
StoreAdapterToATInstanceMap(AXI.axi_index,g_IpInfo.arpEntTable[i]);
}
TraceLeave("UpdateAdapterToATInstanceMap");
return NO_ERROR;
}
DWORD
GetIpNetTableFromStackEx(LPDWORD arpEntTable,
DWORD dwValidArpEntEntries,
IPNetToMediaEntry **lpNetTable,
LPDWORD lpdwTotalEntries,
LPDWORD lpdwValidEntries,
BOOL bOrder,
HANDLE hHeap)
{
DWORD dwResult;
DWORD dwInBufLen;
DWORD dwOutBufLen;
DWORD i,j;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
UCHAR *Context;
DWORD dwNetEntryCount,dwNumAdded,dwValidNetEntries;
DWORD dwSize,dwNeed;
AddrXlatInfo AXI;
IPNetToMediaEntry *lpOutBuf,tempEntry;
dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
Context = &(trqiInBuf.Context[0]);
ZeroMemory( Context, CONTEXT_SIZE );
ID = &(trqiInBuf.ID);
ID->toi_entity.tei_entity = AT_ENTITY;
ID->toi_type = INFO_TYPE_PROVIDER;
dwNetEntryCount = 0;
for (i = 0; i < dwValidArpEntEntries; i++ )
{
// First add up the AXI counts
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_id = AT_MIB_ADDRXLAT_INFO_ID;
ID->toi_entity.tei_instance = arpEntTable[i];
dwSize = sizeof(AXI);
ZeroMemory(Context, CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
&AXI,
&dwSize );
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"GetIpNetTableFromStackEx: NtStatus %x querying information from stack",
dwResult);
TraceLeave("GetIpNetTableFromStackEx");
return dwResult;
}
//
// At this point map the index to the instance - the index is the adapter
// index though the instance is not the same as IFInstance
//
StoreAdapterToATInstanceMap(AXI.axi_index,arpEntTable[i]);
dwNetEntryCount += AXI.axi_count;
}
//
// This is generally a memory hog
//
dwNeed = dwNetEntryCount + (dwValidArpEntEntries) * SPILLOVER;
if(dwNeed > *lpdwTotalEntries)
{
if(*lpdwTotalEntries)
{
HeapFree(hHeap,0,*lpNetTable);
}
dwNeed += MAX_DIFF;
//
// Serialize the heap ???
//
*lpNetTable = (IPNetToMediaEntry*)HeapAlloc(hHeap,0,
dwNeed*sizeof(IPNetToMediaEntry));
if(*lpNetTable is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"GetIpNetTableFromStackEx: Error %d allocating memory for IpNetTable",
dwResult);
return ERROR_NOT_ENOUGH_MEMORY;
}
*lpdwTotalEntries = dwNeed;
}
else
{
dwNeed = *lpdwTotalEntries;
}
lpOutBuf = *lpNetTable;
dwOutBufLen = dwNeed * sizeof(IPNetToMediaEntry);
dwValidNetEntries = 0;
for(i = 0; i < dwValidArpEntEntries; i++ )
{
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_id = AT_MIB_ADDRXLAT_ENTRY_ID;
ID->toi_entity.tei_instance = arpEntTable[i];
ZeroMemory( Context, CONTEXT_SIZE );
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)lpOutBuf,
&dwOutBufLen);
if ( dwResult isnot NO_ERROR )
{
Trace1(ERR,
"GetIpNetTableFromStackEx: Error %x getting AT Entry",
dwResult);
continue;
}
dwNumAdded = dwOutBufLen/(sizeof(IPNetToMediaEntry));
lpOutBuf += dwNumAdded;
dwValidNetEntries += dwNumAdded;
dwOutBufLen = (dwNeed - dwValidNetEntries) * sizeof(IPNetToMediaEntry);
}
dwResult = NO_ERROR;
*lpdwValidEntries = dwValidNetEntries;
//
// Now sort the net table
//
if(dwValidNetEntries > 0)
{
for(i = 0; i < dwValidNetEntries; i++)
{
(*lpNetTable)[i].inme_index = GetInterfaceFromAdapter((*lpNetTable)[i].inme_index);
}
if(bOrder)
{
for(i = 0; i < dwValidNetEntries - 1; i++)
{
DWORD min = i;
for(j = i + 1; j < dwValidNetEntries; j++)
{
if(IpNetCmp((*lpNetTable)[min].inme_index,(*lpNetTable)[min].inme_addr,
(*lpNetTable)[j].inme_index,(*lpNetTable)[j].inme_addr) > 0)
{
min = j;
}
}
if(min isnot i)
{
tempEntry = (*lpNetTable)[min];
(*lpNetTable)[min] = (*lpNetTable)[i];
(*lpNetTable)[i] = tempEntry;
}
}
}
}
TraceLeave("GetIpNetTableFromStackEx");
return dwResult;
}
DWORD
SetIpNetEntryToStack(IPNetToMediaEntry *inmeEntry, DWORD dwInstance)
{
TCP_REQUEST_SET_INFORMATION_EX *lptrsiInBuf;
TDIObjectID *ID;
UCHAR *Context;
IPNetToMediaEntry *copyInfo;
DWORD dwInBufLen,dwOutBufLen,dwResult;
TraceEnter("SetIpNetEntryToStack");
dwInBufLen = sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(IPNetToMediaEntry) - 1;
lptrsiInBuf = HeapAlloc(GetProcessHeap(),0,dwInBufLen);
if(lptrsiInBuf is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"SetIpNetEntryToStack: Error %d allocating memory",
dwResult);
return dwResult;
}
ID = &lptrsiInBuf->ID;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_entity.tei_entity = AT_ENTITY;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = AT_MIB_ADDRXLAT_ENTRY_ID;
ID->toi_entity.tei_instance = dwInstance;
//
// Since IPNetToMediaEntry is a fixed size structure
//
copyInfo = (IPNetToMediaEntry*)lptrsiInBuf->Buffer;
*copyInfo = *inmeEntry;
dwResult = TCPSetInformationEx(g_hTcpDevice,
(LPVOID)lptrsiInBuf,
&dwInBufLen,
NULL,
&dwOutBufLen);
TraceLeave("SetIpNetEntryToStack");
return dwResult;
}
DWORD
UpdateAdapterToIFInstanceMap()
{
IPSNMPInfo ipsiInfo;
DWORD dwResult;
DWORD dwOutBufLen;
DWORD dwInBufLen;
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
TDIObjectID *ID;
IFEntry *maxIfEntry;
BYTE *Context;
DWORD dwCount,i;
TraceEnter("UpdateAdapterToIFInstanceMap");
dwResult = GetIpStatsFromStack(&ipsiInfo);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"UpdateAdapterToIFInstanceMap: NtStatus %x querying IpSnmpInfo from stack to determine number if interface",
dwResult);
TraceLeave("UpdateAdapterToIFInstanceMap");
return dwResult;
}
dwOutBufLen = sizeof(MIB_IFROW) - FIELD_OFFSET(MIB_IFROW, dwIndex);
if((maxIfEntry = (IFEntry*)HeapAlloc(GetProcessHeap(),
0,
dwOutBufLen)) is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"UpdateAdapterToIFInstanceMap: Error %d allocating memory",
dwResult);
TraceLeave("UpdateAdapterToIFInstanceMap");
return ERROR_NOT_ENOUGH_MEMORY;
}
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
ID = &(trqiInBuf.ID);
Context = &(trqiInBuf.Context[0]);
ID->toi_entity.tei_entity = IF_ENTITY;
ID->toi_class = INFO_CLASS_PROTOCOL;
ID->toi_type = INFO_TYPE_PROVIDER;
ID->toi_id = IF_MIB_STATS_ID;
//
// Read the interface entry items
//
for ( i = 0; i < ipsiInfo.ipsi_numif ; i++ )
{
dwOutBufLen = sizeof(MIB_IFROW) - FIELD_OFFSET(MIB_IFROW, dwIndex);
ID->toi_entity.tei_instance = i;
ZeroMemory(Context,CONTEXT_SIZE);
dwResult = TCPQueryInformationEx(g_hTcpDevice,
&trqiInBuf,
&dwInBufLen,
(LPVOID)maxIfEntry,
&dwOutBufLen);
if (dwResult isnot NO_ERROR)
{
Trace1(ERR,
"UpdateAdapterToIFInstanceMap: NtStatus %x getting IFRow from stack",
dwResult);
continue;
}
StoreAdapterToIFInstanceMap(maxIfEntry->if_index,i);
}
HeapFree(GetProcessHeap(),0,maxIfEntry);
TraceLeave("UpdateAdapterToIFInstanceMap");
return NO_ERROR;
}
//* TCPQueryInformationEx
//
// Description: Get information from the stack.
//
// Parameters: HANDLE hHandle: handle to the stack.
// TDIObjectID *ID: pointer to TDIObjectID info.
// void *Buffer: buffer to receive data from the stack.
// ulong *Bufferlen: IN: tells stack size of available buffer,
// OUT: tells us how much data is available.
// CONTEXT *Context: allows queries spanning more than one call.
//
// Returns: int:
//
//*
int
TCPQueryInformationEx( HANDLE hHandle,
void *InBuf,
ulong *InBufLen,
void *OutBuf,
ulong *OutBufLen )
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
TraceEnter("TCPQueryInformationEx");
Status = NtDeviceIoControlFile( hHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TCP_QUERY_INFORMATION_EX,
InBuf,
*InBufLen,
OutBuf,
*OutBufLen );
if ( Status == STATUS_PENDING )
{
Status = NtWaitForSingleObject( hHandle, FALSE, NULL );
Status = IoStatusBlock.Status;
}
if ( !NT_SUCCESS( Status ) )
{
Trace1(ERR,
"TCPQueryInformationEx: NtStatus %x from NtDeviceIoControlFile",
Status);
*OutBufLen = 0;
TraceLeave("TCPQueryInformationEx");
return Status;
}
//
// Tell caller how much was written
//
*OutBufLen = IoStatusBlock.Information;
TraceLeave("TCPQueryInformationEx");
return NO_ERROR;
}
//* TCPSetInformationEx()
//
// Description: Send information to the stack
//
// Parameters: HANDLE hHandle: handle to the stack.
// TDIObjectID *ID: pointer to TDIObjectID info.
// void *Buffer: buffer to receive data from the stack.
// ulong Bufferlen: tells stack size of available buffer,
//
// Returns: int:
//
//*
int
TCPSetInformationEx(HANDLE hHandle,
void *InBuf,
ULONG *InBufLen,
void *OutBuf,
ULONG *OutBufLen )
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
TraceEnter("TCPSetInformationEx");
Status = NtDeviceIoControlFile(hHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_TCP_SET_INFORMATION_EX,
InBuf,
*InBufLen,
OutBuf,
*OutBufLen );
if ( Status == STATUS_PENDING )
{
Status = NtWaitForSingleObject(hHandle, FALSE, NULL );
Status = IoStatusBlock.Status;
}
if ( !NT_SUCCESS( Status ) )
{
Trace1(ERR,
"TCPSetInformationEx: NtStatus %x from NtDeviceIoControlFile",
Status);
TraceLeave("TCPSetInformationEx");
return Status;
}
TraceLeave("TCPSetInformationEx");
return NO_ERROR;
}