|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
stackex.c
Abstract:
Ex versions of GetTcpTableFromStack and GetUdpTableFromStack. These are used to get the owning process id associated with connections from the stack.
Author:
Shaun Cox (shaunco) 19-Feb-2000
Revision History:
--*/
#include "inc.h"
#pragma hdrstop
int TCPQueryInformationEx( DWORD Family, void *InBuf, ulong *InBufLen, void *OutBuf, ulong *OutBufLen );
DWORD GetTcpExTableFromStack( OUT TCP_EX_TABLE *pTcpTable, IN DWORD dwSize, IN BOOL bOrder, IN DWORD dwFamily ) { DWORD dwInBufLen, dwOutBufLen, dwResult, dwEntryLen; TDIObjectID *ID; BYTE *Context; int (_cdecl *pfnCompare)(CONST VOID *pvElem1, CONST VOID *pvElem2);
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
CheckTcpipState(); if (dwFamily == AF_INET) { if (!g_bIpConfigured) { return ERROR_NOT_SUPPORTED; } dwEntryLen = sizeof(TCPConnTableEntryEx); pfnCompare = CompareTcpRow; dwOutBufLen = dwSize - FIELD_OFFSET(TCP_EX_TABLE, table[0]); } else if (dwFamily == AF_INET6) { if (!g_bIp6Configured) { return ERROR_NOT_SUPPORTED; } dwEntryLen = sizeof(TCP6ConnTableEntry); pfnCompare = CompareTcp6Row; dwOutBufLen = dwSize - FIELD_OFFSET(TCP6_EX_TABLE, table[0]); } else { return ERROR_INVALID_PARAMETER; }
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_EX_TABLE_ID;
Context = (BYTE *) &(trqiInBuf.Context[0]); ZeroMemory( Context, CONTEXT_SIZE );
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
dwResult = TCPQueryInformationEx(dwFamily, &trqiInBuf, &dwInBufLen, (PVOID)(pTcpTable->table), &dwOutBufLen);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "GetTcpExTableFromStack: Couldnt query stack. Error %x", dwResult);
return dwResult; }
pTcpTable->dwNumEntries = (dwOutBufLen / dwEntryLen);
if((pTcpTable->dwNumEntries > 0) and bOrder) {
qsort(pTcpTable->table, pTcpTable->dwNumEntries, dwEntryLen, pfnCompare);
}
return NO_ERROR; }
DWORD AllocateAndGetTcpExTableFromStack( OUT TCP_EX_TABLE **ppTcpTable, IN BOOL bOrder, IN HANDLE hHeap, IN DWORD dwFlags, IN DWORD dwFamily ) { DWORD dwResult, dwCount, dwOutBufLen; MIB_TCPSTATS TcpInfo; DWORD dwEntryLen;
*ppTcpTable = NULL;
//
// Find out the number of entries the stack has. It returns this as part of
// the Tcp Stats. Also validate the dwFamily parameter.
//
dwResult = GetTcpStatsFromStackEx(&TcpInfo, dwFamily);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "AllocateAndGetTcpExTableFromStack: Couldnt get Tcp Stats From stack. Error %d", dwResult);
return dwResult; } dwCount = TcpInfo.dwNumConns + OVERFLOW_COUNT;
if (dwFamily == AF_INET) { dwEntryLen = sizeof(TCPConnTableEntryEx); dwOutBufLen = FIELD_OFFSET(TCP_EX_TABLE, table[0]) + (dwCount * dwEntryLen) + ALIGN_SIZE; } else { dwEntryLen = sizeof(TCP6ConnTableEntry); dwOutBufLen = FIELD_OFFSET(TCP6_EX_TABLE, table[0]) + (dwCount * dwEntryLen) + ALIGN_SIZE; }
*ppTcpTable = HeapAlloc(hHeap, dwFlags, dwOutBufLen); if(*ppTcpTable is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR, "AllocateAndGetTcpExTableFromStack: Couldnt allocate memory. Error %d", dwResult);
return dwResult; }
if(TcpInfo.dwNumConns is 0) { (*ppTcpTable)->dwNumEntries = 0;
return NO_ERROR; }
dwResult = GetTcpExTableFromStack(*ppTcpTable, dwOutBufLen, bOrder, dwFamily);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "AllocateAndGetTcpExTableFromStack: Error %d GetTcpExTableFromStack", dwResult); }
return dwResult; }
DWORD GetUdpExTableFromStack( OUT UDP_EX_TABLE *pUdpTable, IN DWORD dwSize, IN BOOL bOrder, IN DWORD dwFamily ) { DWORD dwInBufLen, dwOutBufLen, dwResult; BYTE *Context; DWORD dwEntryLen; int (__cdecl *pfnCompare)(CONST VOID *pvElem1, CONST VOID *pvElem2);
TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf; TDIObjectID *ID;
CheckTcpipState();
if (dwFamily == AF_INET) { if (!g_bIpConfigured) { return ERROR_NOT_SUPPORTED; } dwEntryLen = sizeof(UDPEntryEx); pfnCompare = CompareUdpRow; } else if (dwFamily == AF_INET6) { if (!g_bIp6Configured) { return ERROR_NOT_SUPPORTED; } dwEntryLen = sizeof(UDP6ListenerEntry); pfnCompare = CompareUdp6Row; } else { return ERROR_INVALID_PARAMETER; }
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_EX_TABLE_ID;
Context = (BYTE *) &(trqiInBuf.Context[0]); ZeroMemory( Context, CONTEXT_SIZE );
dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX); dwOutBufLen = dwSize - FIELD_OFFSET(UDP6_LISTENER_TABLE, table[0]);
dwResult = TCPQueryInformationEx(dwFamily, &trqiInBuf, &dwInBufLen, (PVOID)(pUdpTable->table), &dwOutBufLen);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "GetUdpExTableFromStack: Couldnt query TCP information. Error %d", dwResult);
return dwResult; }
pUdpTable->dwNumEntries = (dwOutBufLen / dwEntryLen);
//
// Now sort the UDP connection table. Keys are: local address, and local
// port.
//
if((pUdpTable->dwNumEntries > 0) and bOrder) { qsort(pUdpTable->table, pUdpTable->dwNumEntries, dwEntryLen, pfnCompare); }
TraceLeave("GetUdpExTableFromStack");
return NO_ERROR; }
DWORD AllocateAndGetUdpExTableFromStack( OUT UDP_EX_TABLE **ppUdpTable, IN BOOL bOrder, IN HANDLE hHeap, IN DWORD dwFlags, IN DWORD dwFamily ) { DWORD dwResult, dwCount, dwOutBufLen; MIB_UDPSTATS UdpInfo;
*ppUdpTable = NULL;
//
// Find out the number of entries the stack has. It returns this as part of
// the Tcp Stats. Also validate the dwFamily parameter.
//
dwResult = GetUdpStatsFromStackEx(&UdpInfo, dwFamily);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "AllocateAndGetUdpExTableFromStack: Couldnt get Udp Stats From stack. Error %d", dwResult);
return dwResult; }
dwCount = UdpInfo.dwNumAddrs + OVERFLOW_COUNT; if (dwFamily == AF_INET) { dwOutBufLen = FIELD_OFFSET(UDP_EX_TABLE, table[0]) + (dwCount * sizeof(UDPEntryEx)) + ALIGN_SIZE; } else { dwOutBufLen = FIELD_OFFSET(UDP6_LISTENER_TABLE, table[0]) + (dwCount * sizeof(UDP6ListenerEntry)) + ALIGN_SIZE; }
*ppUdpTable = HeapAlloc(hHeap, dwFlags, dwOutBufLen); if(*ppUdpTable is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR, "AllocateAndGetUdpExTableFromStack: Couldnt allocate memory. Error %d", dwResult);
return dwResult; }
if(UdpInfo.dwNumAddrs is 0) { (*ppUdpTable)->dwNumEntries = 0;
return NO_ERROR; }
dwResult = GetUdpExTableFromStack(*ppUdpTable, dwOutBufLen, bOrder, dwFamily);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "AllocateAndGetUdpExTableFromStack: Error %d GetUdpExTableFromStack", dwResult); }
return dwResult; }
DWORD GetBestInterfaceFromIpv6Stack( IN LPSOCKADDR_IN6 pSockAddr, OUT PDWORD pdwBestIfIndex ) { DWORD dwOutBufLen, dwInBufLen, dwResult; CHAR byBuffer[FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context) + sizeof(TDI_ADDRESS_IP6)]; TCP_REQUEST_QUERY_INFORMATION_EX *ptrqiInBuf = (TCP_REQUEST_QUERY_INFORMATION_EX *)byBuffer; IP6RouteEntry Ire; TDIObjectID *ID;
ID = &(ptrqiInBuf->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 = IP6_GET_BEST_ROUTE_ID;
RtlCopyMemory((PVOID)ptrqiInBuf->Context, &pSockAddr->sin6_port, TDI_ADDRESS_LENGTH_IP6);
dwInBufLen = sizeof(byBuffer); dwOutBufLen = sizeof(Ire);
dwResult = TCPQueryInformationEx(AF_INET6, ptrqiInBuf, &dwInBufLen, (PVOID)&Ire, &dwOutBufLen);
if (dwResult isnot NO_ERROR) { Trace1(ERR,"Couldn't query IPv6 stack. Error %d", dwResult); TraceLeave("GetBestInterfaceEx");
return dwResult; }
*pdwBestIfIndex = Ire.ire_IfIndex;
return dwResult; }
|