// TCPTable.cpp: implementation of the CTCPTable class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ENetStat.h"
#include "TCPTable.h"
#include "Base.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
//init static members
MIB_TCPTABLE* CTCPTable::m_pTcpTable = NULL;
MIB_TCPTABLE_EX* CTCPTable::m_pTcpTableEx = NULL;
BYTE* CTCPTable::m_pBuff = NULL;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTCPTable::CTCPTable()
{
m_pTcpTable = NULL;
m_pTcpTableEx = NULL;
m_bEstb = false;
}
//////////////////////////////////////////////////////////////////////
//
CTCPTable::~CTCPTable()
{
delete [] m_pBuff;
}
//////////////////////////////////////////////////////////////////////
//
u_int CTCPTable::GetRecordsNumber()
{
return 1;
}
//////////////////////////////////////////////////////////////////////
//
TCPTABLE CTCPTable::GetTableAtIndex(int nIndex)
{
return m_tcpTab;
}
//////////////////////////////////////////////////////////////////////
//
DWORD CTCPTable::PrintTable(void)
{
//vars
DWORD dwSize = 0;
in_addr stAddr;
in_addr stAddrRem;
CString str = " ";
CString line = " ";
int nSpace = 0;
//get the buff size
GetTcpTable(NULL, &dwSize, FALSE);
//alloc buffer
m_pBuff = new BYTE[dwSize];
//gathering info
if (GetTcpTable((PMIB_TCPTABLE)m_pBuff, &dwSize, TRUE) != NO_ERROR)
{
TRACE("Error: %d, gathering tcp info");
return GetLastError();
}
//manage the buffer
m_pTcpTable = (PMIB_TCPTABLE)m_pBuff;
//print the info
printf("\n Proto \tLocal Address Local Port Remote Address Remote Port \tConnection State");
for (int i = 0; i < m_pTcpTable->dwNumEntries; i++)
{
//prepare the local address field
u_long ulLocalAddress = static_cast<u_long>(m_pTcpTable->table[i].dwLocalAddr);
stAddr.s_addr = ulLocalAddress; //stAddr.S_un.S_addr = stAddr.s_addr
//prepare the local port field
u_short usLocalPort = ntohs(m_pTcpTable->table[i].dwLocalPort);
//prepare the remote address field
u_long ulRemoteAddress = static_cast<u_long>(m_pTcpTable->table[i].dwRemoteAddr);
stAddrRem.s_addr = ulRemoteAddress;
//prepare the local port field
u_short usRemotePort = ntohs(m_pTcpTable->table[i].dwRemotePort);
if ((m_bEstb == true) && (m_pTcpTable->table[i].dwState == MIB_TCP_STATE_ESTAB))
{
//print info for locals
printf("\n TCP\t%s ", inet_ntoa(stAddr));
str = inet_ntoa(stAddr);
nSpace = str.GetLength();
for (; nSpace <= 16; nSpace++) printf(" ");
printf("\t %u", usLocalPort);
str.Empty();
//printf("\n TCP\t%s \t%u", inet_ntoa(stAddr), usLocalPort);
//print info for remote
printf(" \t\t%s", inet_ntoa(stAddrRem));
str = inet_ntoa(stAddrRem);
nSpace = str.GetLength();
for (; nSpace <= 16; nSpace++) printf(" ");
printf("\t %u", usRemotePort);
//printf("\t\t%s \t%u", inet_ntoa(stAddrRem), usRemotePort);
//print info for state
printf("\t\t%s", Convert2State(m_pTcpTable->table[i].dwState));
}
else if(m_bEstb == false)
{
//print info for locals
printf("\n TCP\t%s ", inet_ntoa(stAddr));
str = inet_ntoa(stAddr);
nSpace = str.GetLength();
for (; nSpace <= 16; nSpace++) printf(" ");
printf("\t %u", usLocalPort);
str.Empty();
//printf("\n TCP\t%s \t%u", inet_ntoa(stAddr), usLocalPort);
//print info for remote
printf(" \t\t%s", inet_ntoa(stAddrRem));
str = inet_ntoa(stAddrRem);
nSpace = str.GetLength();
for (; nSpace <= 16; nSpace++) printf(" ");
printf("\t %u", usRemotePort);
//printf("\t\t%s \t%u", inet_ntoa(stAddrRem), usRemotePort);
//print info for state
printf("\t\t%s", Convert2State(m_pTcpTable->table[i].dwState));
}
}
return 1;
}
//////////////////////////////////////////////////////////////////////
//
DWORD CTCPTable::PrintTableEx(void)
{
//vars
HMODULE hmModule = NULL;
in_addr stAddr;
in_addr stAddrRem;
DWORD dwSize = 0;
CBase *pBase = new CBase();
CString strPath;
//imported method
pAllocateAndGetTcpExTableFromStack pGetTcpTableEx = NULL;
if(pBase != NULL)
{
//prepare the path
strPath = pBase->GetSysPath() + "\\system32\\iphlpapi.dll";
//release unused objects
delete pBase;
pBase = NULL;
}
//load "iphlpapi.dll"
hmModule = ::LoadLibrary(strPath);
if(hmModule == NULL)
return ::GetLastError();
//alloc buff
PMIB_TCPTABLE_EX m_pBuffTcpTableEx;
//point to the magic method
pGetTcpTableEx = (pAllocateAndGetTcpExTableFromStack) GetProcAddress(
hmModule, "AllocateAndGetTcpExTableFromStack");
if(pGetTcpTableEx == NULL)
return ::GetLastError();
//gathering info
(pGetTcpTableEx) (&m_pBuffTcpTableEx, TRUE, GetProcessHeap(), 0, 2);
//print the info
printf("\n Proto \tPid \tProcess Name \tLocal Address \tLocal Port \tRemote Address \tRemote Port \tConnection State");
for (int i = 0; i < m_pBuffTcpTableEx->dwNumEntries; i++)
{
//prepare the local address field
u_long ulLocalAddress = static_cast<u_long>(m_pBuffTcpTableEx->table[i].dwLocalAddr);
stAddr.s_addr = ulLocalAddress; //stAddr.S_un.S_addr = stAddr.s_addr
//prepare the local port field
u_short usLocalPort = ntohs(m_pBuffTcpTableEx->table[i].dwLocalPort);
//prepare the remote address field
u_long ulRemoteAddress = static_cast<u_long>(m_pBuffTcpTableEx->table[i].dwRemoteAddr);
stAddrRem.s_addr = ulRemoteAddress;
//prepare the local port field
u_short usRemotePort = ntohs(m_pBuffTcpTableEx->table[i].dwRemotePort);
//prepare the Pid
DWORD dwPid = m_pBuffTcpTableEx->table[i].dwProcessId;
CString strProcName = pBase->GetProcById(m_pBuffTcpTableEx->table[i].dwProcessId);
if ((m_bEstb == true) && (m_pBuffTcpTableEx->table[i].dwState == MIB_TCP_STATE_ESTAB))
{
Conn2Console(dwPid,strProcName,inet_ntoa(stAddr),usLocalPort,inet_ntoa(stAddrRem),usRemotePort);
printf("\t\t%s", Convert2State(m_pBuffTcpTableEx->table[i].dwState));
}
else if(m_bEstb == false)
{
Conn2Console(dwPid,strProcName,inet_ntoa(stAddr),usLocalPort,inet_ntoa(stAddrRem),usRemotePort); //print info for state
printf("\t\t%s", Convert2State(m_pBuffTcpTableEx->table[i].dwState));
}
}
if (0 == FreeLibrary(hmModule))
return ::GetLastError();
return 1;
}
//////////////////////////////////////////////////////////////////////
//
bool CTCPTable::KillConnection(u_long ulRemIP, u_short usLocalPort)
{
u_long ulLocIP = 0;
u_short usRemPort = 0;
MIB_TCPROW sKillConn;
if (false == GetMatchingConn(ulRemIP, usLocalPort, &ulLocIP, &usRemPort))
{
printf("\n Error closing connection ;(\n");
return false;
}
sKillConn.dwLocalAddr = (DWORD)ulLocIP;
sKillConn.dwLocalPort = (DWORD)usLocalPort;
sKillConn.dwRemoteAddr = (DWORD)ulRemIP;
sKillConn.dwRemotePort = (DWORD)usRemPort;
sKillConn.dwState = MIB_TCP_STATE_DELETE_TCB;
DWORD dwRez = SetTcpEntry(&sKillConn);
if(dwRez != NO_ERROR)
{
dwRez = ::GetLastError();
printf("\nError closing connection ;(\n");
return false;
}
printf("\nConnection closed succesfully ;)\n");
return true;
}
//////////////////////////////////////////////////////////////////////
//
CString CTCPTable::Convert2State(DWORD dwState)
{
switch(dwState)
{
case MIB_TCP_STATE_CLOSED:
return "CLOSED";
case MIB_TCP_STATE_LISTEN:
return "LISTEN";
case MIB_TCP_STATE_SYN_SENT:
return "SYN_SENT";
case MIB_TCP_STATE_SYN_RCVD:
return "SYN_RCVD";
case MIB_TCP_STATE_ESTAB:
return "ESTAB";
case MIB_TCP_STATE_FIN_WAIT1:
return "FIN_WAIT1";
case MIB_TCP_STATE_FIN_WAIT2:
return "FIN_WAIT2";
case MIB_TCP_STATE_CLOSE_WAIT:
return "CLOSE_WAIT";
case MIB_TCP_STATE_CLOSING:
return "CLOSING";
case MIB_TCP_STATE_LAST_ACK:
return "LAST_ACK";
case MIB_TCP_STATE_TIME_WAIT:
return "TIME_WAIT";
case MIB_TCP_STATE_DELETE_TCB:
return "DELETE_TCB";
default:
return "UNKNOWN";
}
}
//////////////////////////////////////////////////////////////////////
//
void CTCPTable::Conn2Console(DWORD dwPid, \
CString strProcName, \
CString strLocAddress, \
u_short usLocalPort, \
CString strRemAddress, \
u_short usRemotePort)
{
//print info for locals
printf("\n TCP \t%d \t%s \t%s \t%u", dwPid, strProcName, strLocAddress, usLocalPort);
//print info for remote
printf("\t\t%s \t%u", strRemAddress, usRemotePort);
}
//////////////////////////////////////////////////////////////////////
//
bool CTCPTable::GetMatchingConn(u_long ulRemAdr, u_short usLocPort, u_long* ulLocAdr, u_short* usRemPort)
{
//vars
DWORD dwSize = 0;
*ulLocAdr = 0;
*usRemPort= 0;
//get the buff size
GetTcpTable(NULL, &dwSize, FALSE);
//alloc buffer
m_pBuff = new BYTE[dwSize];
//gathering info
if (GetTcpTable((PMIB_TCPTABLE)m_pBuff, &dwSize, TRUE) != NO_ERROR)
{
TRACE("Error: %d, gathering tcp info");
return false;
}
//manage the buffer
m_pTcpTable = (PMIB_TCPTABLE)m_pBuff;
for (int i = 0; i < m_pTcpTable->dwNumEntries; i++)
{
u_long ulLocalAddress = (u_long)m_pTcpTable->table[i].dwLocalAddr;
u_short usLocalPort = m_pTcpTable->table[i].dwLocalPort;
u_long ulRemoteAddress = (u_long)m_pTcpTable->table[i].dwRemoteAddr;
u_short usRemotePort = m_pTcpTable->table[i].dwRemotePort;
if ((m_pTcpTable->table[i].dwState == MIB_TCP_STATE_ESTAB) && \
(usLocPort == usLocalPort) && \
(ulRemAdr == ulRemoteAddress))
{
*ulLocAdr = ulLocalAddress;
*usRemPort = usRemotePort;
return true;
}
}
return false;
}