#include <winsock2.h>
#include <windows.h>
#include <iphlpapi.h>
#include <cstdio>
#include <conio.h>
#include <string>
using namespace std;
#pragma comment ( lib, "ws2_32.lib" )
#pragma comment ( lib, "iphlpapi.lib" )
#define DECLAREFUNC(func) p##func func;
#define GETFUNCADDR(lib, func) func = ( p##func ) GetProcAddress( lib, #func )
#define GETLIBHANDLE(handle, lib) HMODULE (handle) = GetModuleHandle(lib); if((handle) == NULL) (handle) = LoadLibrary(lib);
// === Structures declaration ===
typedef struct _MIB_TCPROW_EX {
DWORD dwState;
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwRemoteAddr;
DWORD dwRemotePort;
DWORD dwProcessId;
} MIB_TCPROW_EX, *PMIB_TCPROW_EX;
typedef struct _MIB_TCPTABLE_EX {
DWORD dwNumEntries;
MIB_TCPROW_EX table[ANY_SIZE];
} MIB_TCPTABLE_EX, *PMIB_TCPTABLE_EX;
// only for XP+
typedef struct _MIB_UDPROW_EX {
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwProcessId;
} MIB_UDPROW_EX, *PMIB_UDPROW_EX;
typedef struct _MIB_UDPTABLE_EX {
DWORD dwNumEntries;
MIB_UDPROW_EX table[ANY_SIZE];
} MIB_UDPTABLE_EX, *PMIB_UDPTABLE_EX;
// ===
Function declaration ===
typedef DWORD (WINAPI *pAllocateAndGetTcpTableFromStack)(
PMIB_TCPTABLE *pTcpTable,
BOOL bOrder,
HANDLE hAllocHeap,
DWORD dwAllocFlags,
DWORD dwProtocolVersion
);
typedef DWORD (WINAPI *pAllocateAndGetUdpTableFromStack)(
PMIB_UDPTABLE *pUdpTable,
BOOL bOrder,
HANDLE hAllocHeap,
DWORD dwAllocFlags,
DWORD dwProtocolVersion
);
// Only for XP+
typedef DWORD (WINAPI *pAllocateAndGetTcpExTableFromStack)(
PMIB_TCPTABLE_EX *pTcpTableEx,
BOOL bOrder,
HANDLE hAllocHeap,
DWORD dwAllocFlags,
DWORD dwProtocolVersion
);
typedef DWORD (WINAPI *pAllocateAndGetUdpExTableFromStack)(
PMIB_UDPTABLE_EX *pUdpTableEx,
BOOL bOrder,
HANDLE hAllocHeap,
DWORD dwAllocFlags,
DWORD dwProtocolVersion
);
class NetStat {
private:
bool useExFunc;
DECLAREFUNC( AllocateAndGetTcpTableFromStack );
DECLAREFUNC( AllocateAndGetUdpTableFromStack );
DECLAREFUNC( AllocateAndGetTcpExTableFromStack );
DECLAREFUNC( AllocateAndGetUdpExTableFromStack );
string FmtAddrPort( DWORD Addr, DWORD Port, bool remote ){
string res = "";
char buff[22];
in_addr ia;
ia.S_un.S_addr = Addr;
sprintf( buff, "%s:%d",
inet_ntoa( ia ), ( remote && Addr == 0 ) ? 0 : ntohs( LOWORD( Port ) ) );
res.append( buff );
return res;
}
string FmtState( DWORD State ){
string res;
switch( State ){
case MIB_TCP_STATE_CLOSED : res = "CLOSED";
case MIB_TCP_STATE_LISTEN : res = "LISTENING"; break;
case MIB_TCP_STATE_SYN_SENT : res = "SYN_SENT"; break;
case MIB_TCP_STATE_SYN_RCVD : res = "SYN_RCVD"; break;
case MIB_TCP_STATE_ESTAB : res = "ESTABLISHED"; break;
case MIB_TCP_STATE_FIN_WAIT1 : res = "FIN_WAIT1"; break;
case MIB_TCP_STATE_FIN_WAIT2 : res = "FIN_WAIT2"; break;
case MIB_TCP_STATE_CLOSE_WAIT : res = "CLOSE_WAIT"; break;
case MIB_TCP_STATE_CLOSING : res = "CLOSING"; break;
case MIB_TCP_STATE_LAST_ACK : res = "LAST_ACK"; break;
case MIB_TCP_STATE_TIME_WAIT : res = "TIME_WAIT"; break;
case MIB_TCP_STATE_DELETE_TCB : res = "
ELETE_TCB"; break;
}
return res;
}
public:
NetStat(){
GETLIBHANDLE( hIPHlpAPILib, "iphlpapi.dll" );
useExFunc = isXP();
if( useExFunc ){
GETFUNCADDR( hIPHlpAPILib, AllocateAndGetTcpExTableFromStack );
GETFUNCADDR( hIPHlpAPILib, AllocateAndGetUdpExTableFromStack );
if( AllocateAndGetTcpExTableFromStack == NULL ) throw;
if( AllocateAndGetUdpExTableFromStack == NULL ) throw;
} else{
GETFUNCADDR( hIPHlpAPILib, AllocateAndGetTcpTableFromStack );
GETFUNCADDR( hIPHlpAPILib, AllocateAndGetUdpTableFromStack );
if( AllocateAndGetTcpTableFromStack == NULL ) throw;
if( AllocateAndGetUdpTableFromStack == NULL ) throw;
}
}
bool isXP(){
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi );
return ( osvi.dwMajorVersion > 5 ||
osvi.dwMajorVersion == 5 && osvi.dwMinorVersion >= 1 );
}
void GetTable(){
if( useExFunc ){
GetTableXP();
} else{
GetTableNoXP();
}
}
void GetTableNoXP(){
// === TCP ===
MIB_TCPTABLE *pTcpT;
DWORD Bytes = 0;
GetTcpTable( NULL, &Bytes, 1 );
pTcpT = new MIB_TCPTABLE [Bytes / sizeof( MIB_TCPTABLE )];
GetTcpTable( pTcpT, &Bytes, 1 );
printf( "Proto
Local Remote State\n"
"===============================================================\n" );
for(DWORD i = 0; i < pTcpT->dwNumEntries; i++){
printf( " TCP %-22s %-22s %s\n",
FmtAddrPort( pTcpT->table[i].dwLocalAddr, pTcpT->table[i].dwLocalPort, false ).c_str(),
FmtAddrPort( pTcpT->table[i].dwRemoteAddr, pTcpT->table[i].dwRemotePort, true ).c_str(),
FmtState( pTcpT->table[i].dwState ).c_str() );
}
delete [] pTcpT;
// === UDP ===
MIB_UDPTABLE *pUdpT;
Bytes = 0;
GetUdpTable( NULL, &Bytes, 1 );
pUdpT = new MIB_UDPTABLE [Bytes / sizeof( MIB_UDPTABLE )];
GetUdpTable( pUdpT, &Bytes, 1 );
for(DWORD i = 0; i < pUdpT->dwNumEntries; i++){
printf( " UDP %-22s %-22s %s\n",
FmtAddrPort( pUdpT->table[i].dwLocalAddr, pUdpT->table[i].dwLocalPort, false ).c_str(),
"*:*", " " );
}
delete [] pUdpT;
}
void GetTableXP(){
// === TCP ===
PMIB_TCPTABLE_EX pTcpT = ( PMIB_TCPTABLE_EX )HeapAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( PMIB_TCPTABLE_EX ) );
AllocateAndGetTcpExTableFromStack(
&pTcpT, true, GetProcessHeap(), HEAP_ZERO_MEMORY, AF_INET);
printf( "Proto
Local Remote PID State\n"
"=====================================================================\n"
;
for(DWORD i = 0; i < pTcpT->dwNumEntries; i++){
printf( " TCP %-22s %-22s %-5d %s\n",
FmtAddrPort( pTcpT->table[i].dwLocalAddr, pTcpT->table[i].dwLocalPort, false ).c_str(),
FmtAddrPort( pTcpT->table[i].dwRemoteAddr, pTcpT->table[i].dwRemotePort, true ).c_str(),
pTcpT->table[i].dwProcessId, FmtState( pTcpT->table[i].dwState ).c_str() );
}
HeapFree( GetProcessHeap(), 0, pTcpT );
// === UDP ===
PMIB_UDPTABLE_EX pUdpT = ( PMIB_UDPTABLE_EX )HeapAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( PMIB_UDPTABLE_EX ) );
AllocateAndGetUdpExTableFromStack(
&pUdpT, true, GetProcessHeap(), HEAP_ZERO_MEMORY, AF_INET);
for(DWORD i = 0; i < pUdpT->dwNumEntries; i++){
printf( " UDP %-22s %-22s %-5d %s\n",
FmtAddrPort( pUdpT->table[i].dwLocalAddr, pUdpT->table[i].dwLocalPort, false ).c_str(),
"*:*",
pUdpT->table[i].dwProcessId, " " );
}
HeapFree( GetProcessHeap(), 0, pUdpT );
}
};
int main(){
WSADATA wd;
WSAStartup( 0x101, &wd );
NetStat *ns = NULL;
try {
ns = new NetStat;
} catch( ... ){
delete ns;
MessageBox( 0, "
Error!", "res", MB_ICONERROR );
}
ns->GetTable();
if( ns != NULL ) delete ns;
WSACleanup();
getch();
return 0;
}