// NetStat_Src.cpp : 定义控制台应用程序的入口点。
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <winsock.h>
//#include <winsock2.h>
#include <iphlpapi.h>
//#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")
//---------------------------------------------------------------------------
#define TCP_TYPE 1
#define UDP_TYPE 0
// 以下为与TCP相关的结构.
typedef struct tagMIB_TCPEXROW{
DWORD dwState; // 连接状态.
DWORD dwLocalAddr; // 本地地址.
DWORD dwLocalPort; // 本地端口.
DWORD dwRemoteAddr; // 远程地址.
DWORD dwRemotePort; // 远程端口.
int dwProcessId; //进程pid
} MIB_TCPEXROW, *PMIB_TCPEXROW;
typedef struct tagMIB_TCPEXTABLE{
DWORD dwNumEntries;
MIB_TCPEXROW table[100]; // 任意大小数组变量.
} MIB_TCPEXTABLE, *PMIB_TCPEXTABLE;
//---------------------------------------------------------------------------
// 以下为与UDP相关的结构.
typedef struct tagMIB_UDPEXROW{
DWORD dwLocalAddr; // 本地计算机地址.
DWORD dwLocalPort; // 本地计算机端口.
int dwProcessId; //进程id
} MIB_UDPEXROW, *PMIB_UDPEXROW;
typedef struct tagMIB_UDPEXTABLE{
DWORD dwNumEntries;
MIB_UDPEXROW table[100]; // 任意大小数组变量.
} MIB_UDPEXTABLE, *PMIB_UDPEXTABLE;
//---------------------------------------------------------------------------
// 所用的iphlpapi.dll中的函数原型定义.
// XP 系统下UDP和TCP表
typedef DWORD (WINAPI *PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK)(
PMIB_TCPEXTABLE *pTcpTable,
BOOL bOrder,
HANDLE heap,
DWORD zero,
DWORD flags
);
typedef DWORD (WINAPI *PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK)(
PMIB_UDPEXTABLE *pUdpTable,
BOOL bOrder,
HANDLE heap,
DWORD zero,
DWORD flags
);
//VISTA 系统下UDP和TCP表
//typedef DWORD (WINAPI *_InternalGetTcpTable2)(
// PMIB_TCPTABLE2*pTcpTable_Vista,
// HANDLE heap,
// DWORD flags
// );
//修改版本
typedef DWORD (WINAPI *_InternalGetTcpTable2)(
PMIB_TCPTABLE2 pTcpTable_Vista,
PULONG SizePointer,
BOOL Order
);
typedef DWORD (WINAPI *_InternalGetUdpTableWithOwnerPid)(
PMIB_UDPEXTABLE *pUdpTable,
HANDLE heap,
DWORD flags
);
//XP系统下 TCP UDP函数指针初始化
static PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK pAllocateAndGetTcpExTableFromStack = NULL;
static PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK pAllocateAndGetUdpExTableFromStack = NULL;
static _InternalGetTcpTable2 pGetTcpTable = NULL;
static _InternalGetUdpTableWithOwnerPid pGetUdpTable = NULL;
//全局变量定义区
MIB_TCPTABLE2 g_TcpTable;
//---------------------------------------------------------------------------
//
// 可能的 TCP 端点状态.
//
static char TcpState[][32] = {
TEXT("???"),
TEXT("CLOSED"),
TEXT("LISTENING"),
TEXT("SYN_SENT"),
TEXT("SYN_RCVD"),
TEXT("ESTABLISHED"),
TEXT("FIN_WAIT1"),
TEXT("FIN_WAIT2"),
TEXT("CLOSE_WAIT"),
TEXT("CLOSING"),
TEXT("LAST_ACK"),
TEXT("TIME_WAIT"),
TEXT("DELETE_TCB")
};
///////////////////////////////函数声明区///////////////////////////////////////////
DWORD GetAllPortByProcessId(BOOL type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen);
//---------------------------------------------------------------------------
//
// 生成IP地址字符串.
//
PCHAR GetIP(unsigned int ipaddr)
{
static char pIP[20];
unsigned int nipaddr = htonl(ipaddr);
sprintf(pIP, "%d.%d.%d.%d",
(nipaddr >>24) &0xFF,
(nipaddr>>16) &0xFF,
(nipaddr>>8) &0xFF,
(nipaddr)&0xFF);
return pIP;
}
//---------------------------------------------------------------------------
//
// 由进程号获得全程文件名.
//
char* ProcessPidToName(DWORD ProcessId)
{
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 processEntry = { 0 };
processEntry.dwSize = sizeof(PROCESSENTRY32);
static char ProcessName[256];
lstrcpy(ProcessName, "Idle");
if (hProcessSnap == INVALID_HANDLE_VALUE)
return ProcessName;
BOOL bRet=Process32First(hProcessSnap, &processEntry);
while(bRet)
{
if (processEntry.th32ProcessID == ProcessId)
{
MODULEENTRY32 me32 = {0};
me32.dwSize = sizeof(MODULEENTRY32);
HANDLE hModuleSnap = CreateToolhelp32Snapshot
(TH32CS_SNAPMODULE, processEntry.th32ProcessID);
Module32First(hModuleSnap, &me32); // 获得全程路径.
lstrcpy(ProcessName, me32.szExePath);
CloseHandle(hProcessSnap);
return ProcessName;
}
bRet=Process32Next(hProcessSnap, &processEntry);
}
CloseHandle(hProcessSnap);
return ProcessName;
}
//DWORD GetAllPortByProcessId(BOOL type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen)
//{
// PMIB_TCPEXTABLE TCPExTable;
// PMIB_UDPEXTABLE UDPExTable;
// DWORD dwPortCount = 0;
//
// if(TCP_TYPE == type)//tcp类型
// {
// if(pAllocateAndGetTcpExTableFromStack != NULL)
// {
// if(pAllocateAndGetTcpExTableFromStack(&TCPExTable, TRUE, GetProcessHeap(), 0, AF_INET))//倒数第二个参数
// {
// if (TCPExTable)
// {
// HeapFree(GetProcessHeap(), 0, TCPExTable);
// }
// printf("AllocateAndGetTcpExTableFromStack Error!\n");
// return dwPortCount;
// }
//
// for (UINT i = 0;i<TCPExTable->dwNumEntries;i++)
// {
// if (dwProcessId == TCPExTable->table[i].dwProcessId)//找到对应的pid
// {
// if (dwPortCount < dwMaxLen)
// {
// dwAllPort[dwPortCount] = htons((WORD) TCPExTable->table[i].dwLocalPort);
// dwPortCount++;
// }
// }
// }
// //销毁
// if (TCPExTable)
// {
// HeapFree(GetProcessHeap(), 0, TCPExTable);
// }
// return dwPortCount;
// }
// //xp下的隐藏函数获取失败,则采用Vista下的隐藏函数
// else if (pGetTcpTable != NULL )
// {
// if (pGetTcpTable(&TCPExTable,GetProcessHeap(),1))
// {
// if (TCPExTable)
// {
// HeapFree(GetProcessHeap(), 0, TCPExTable);
// }
// printf("pGetTcpTable Error!.\n");
// return dwPortCount;
// }
//
// //遍历
// for (UINT i = 0;i<TCPExTable->dwNumEntries;i++)
// {
// if (dwProcessId == TCPExTable->table[i].dwProcessId)//找到对应的pid
// {
// if (dwPortCount < dwMaxLen)
// {
// dwAllPort[dwPortCount] = htons((WORD) TCPExTable->table[i].dwLocalPort);
// dwPortCount++;
// }
// }
// }
// //销毁
// if (TCPExTable)
// {
// HeapFree(GetProcessHeap(), 0, TCPExTable);
// }
// return dwPortCount;
// }
//
// }
// else if (UDP_TYPE == type)
// {
// if (pAllocateAndGetUdpExTableFromStack != NULL)
// {
// if(pAllocateAndGetUdpExTableFromStack
// (&UDPExTable, TRUE, GetProcessHeap(), 2, 2 ))
// {
// printf("AllocateAndGetUdpExTableFromStack Error!.\n");
// return dwPortCount;
// }
// }
// else if (pGetUdpTable != NULL)
// {
// if (pGetUdpTable(&UDPExTable,GetProcessHeap(),1))
// {
// printf("pGetUdpTable Error!.\n");
// return dwPortCount;
// }
// }
//
// //遍历
// for (UINT i = 0;i<UDPExTable->dwNumEntries;i++)
// {
// if(dwProcessId == UDPExTable->table->dwProcessId)
// {
// if (dwPortCount < dwMaxLen)
// {
// dwAllPort[dwPortCount] = htons(UDPExTable->table[i].dwLocalPort);
// dwPortCount++;
// }
// }
// }
//
// //销毁
// if (UDPExTable)
// {
// HeapFree(GetProcessHeap(),0,UDPExTable);
// }
// return dwPortCount;
// }
// return dwPortCount;
//}
//---------------------------------------------------------------------------
//
// 显示进程、端口和文件名之间的关联.
//
void DisplayPort()
{
DWORD i;
PMIB_TCPEXTABLE TCPExTable;
PMIB_TCPTABLE2 TCPTable2ForWin7;
PMIB_UDPEXTABLE UDPExTable;
ULONG ulSize = 0;
DWORD dwRetVal = 0;
char szLocalAddress[256];
char szRemoteAddress[256];
//xp下的隐藏函数获取
if(pAllocateAndGetTcpExTableFromStack != NULL && pAllocateAndGetUdpExTableFromStack != NULL)
{
//FALSE or TRUE 表明数据是否排序
if(pAllocateAndGetTcpExTableFromStack(&TCPExTable, FALSE, GetProcessHeap(), 2, AF_INET))//倒数第二个参数
{
printf("AllocateAndGetTcpExTableFromStack Error!\n");
return;
}
//FALSE or TRUE 表明数据是否排序
if(pAllocateAndGetUdpExTableFromStack(&UDPExTable, FALSE, GetProcessHeap(), 2, AF_INET ))
{
printf("AllocateAndGetUdpExTableFromStack Error!.\n");
return;
}
}
//xp下的隐藏函数获取失败,则采用Vista下的隐藏函数
else if (pGetUdpTable != NULL && pGetTcpTable != NULL)
{
//为TCPTable2ForWin7申请内存空间
/*TCPTable2ForWin7 = (MIB_TCPTABLE2 *)HeapAlloc(GetProcessHeap(), 0, sizeof (MIB_TCPTABLE2));
ulSize = sizeof (MIB_TCPTABLE);
if (NULL == TCPTable2ForWin7)
{
printf("allocating memory Error\n");
return ;
}*/
//获取UDP的数据信息
if (pGetUdpTable(&UDPExTable,GetProcessHeap(),1))
{
printf("pGetUdpTable Error!.\n");
return ;
}
/*if ((dwRetVal = pGetTcpTable(TCPTable2ForWin7, &ulSize, TRUE)) ==ERROR_INSUFFICIENT_BUFFER)
{
HeapFree(GetProcessHeap(), 0, TCPTable2ForWin7);
TCPTable2ForWin7 = (MIB_TCPTABLE2 *)HeapAlloc(GetProcessHeap(), 0, ulSize);
if (TCPTable2ForWin7 == NULL)
{
printf("Error allocating memory\n");
return ;
}
}*/
//调用GetTcpTable函数来获取tcp连接信息
ulSize = 50;
pGetTcpTable(&g_TcpTable,&ulSize,TRUE);
/*if ((dwRetVal = pGetTcpTable(TCPTable2ForWin7, &ulSize, TRUE)) == NO_ERROR)
{
}*/
//if (pGetTcpTable(&TCPTable2ForWin7,GetProcessHeap(),1))//更改存储tcp连接信息的类型
//{
// printf("pGetTcpTable Error!.\n");
// return ;
//}
}
printf("%-6s%-22s%-22s%-11s%\n",
TEXT("Proto"),
TEXT("Local Address"),
TEXT("Foreign Address"),
//TEXT("State"),
TEXT("Process"));
////xp下输出TCPExTable中的网络信息
//// 获得TCP列表.
//for( i = 0; i <TCPExTable->dwNumEntries; i++ )
//{
// //构造本地地址
// sprintf( szLocalAddress, "%s:%d",
// GetIP(TCPExTable->table[i].dwLocalAddr),
// htons((WORD) TCPExTable->table[i].dwLocalPort));
// //构造远程地址
// sprintf( szRemoteAddress, "%s:%d",
// GetIP(TCPExTable->table[i].dwRemoteAddr),
// htons((WORD)TCPExTable->table[i].dwRemotePort));
// //输出信息
// printf("%-6s%-22s%-22s%-4d%\n",
// TEXT("TCP"),
// szLocalAddress,
// szRemoteAddress,
// //TEXT("ESTABLISHED"),
// TCPExTable->table[i].dwProcessId);
//}
//Vista 以及Win7下输出网络信息
// 获得TCP列表.
for( i = 0; i <g_TcpTable.dwNumEntries; i++ )
{
//构造本地地址
sprintf( szLocalAddress, "%s:%d",
GetIP(g_TcpTable.table[i].dwLocalAddr),
htons((WORD) g_TcpTable.table[i].dwLocalPort));
//构造远程地址
sprintf( szRemoteAddress, "%s:%d",
GetIP(g_TcpTable.table[i].dwRemoteAddr),
htons((WORD)g_TcpTable.table[i].dwRemotePort));
//输出信息
printf("%-6s%-22s%-22s%-4d%\n",
TEXT("TCP"),
szLocalAddress,
szRemoteAddress,
//TEXT("ESTABLISHED"),
g_TcpTable.table[i].dwOwningPid);
}
//// 获得UDP列表.
//for( i = 0; i < UDPExTable->dwNumEntries; i++ )
//{
// sprintf( szLocalAddress, "%s:%d",
// GetIP(UDPExTable->table[i].dwLocalAddr),
// htons( (WORD)UDPExTable->table[i].dwLocalPort));//本地地址和本地端口
// sprintf( szRemoteAddress, "%s","*:*");
// printf("%-6s%-22s%-22s%-11d%\n",
// TEXT("UDP"),
// szLocalAddress,
// szRemoteAddress,
// //ProcessPidToName(UDPExTable->table[i].dwProcessId),
// UDPExTable->table[i].dwProcessId);
//}
}
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA WSAData;
if( WSAStartup(MAKEWORD(1,1), &WSAData ))//sock version 2.2
{
printf("WSAStartup error!\n");
//return -1;
}
//加载库
HMODULE hIpDLL = LoadLibrary( "iphlpapi.dll");
if ( !hIpDLL)
printf("LoadLibrary error!\n");
//return -1;
//从指定模块获取函数地址 xp
pAllocateAndGetTcpExTableFromStack =
(PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK)
GetProcAddress( hIpDLL,"AllocateAndGetTcpExTableFromStack");
pAllocateAndGetUdpExTableFromStack =
(PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK)
GetProcAddress(hIpDLL, "AllocateAndGetUdpExTableFromStack" );
if (pAllocateAndGetTcpExTableFromStack == NULL
|| pAllocateAndGetUdpExTableFromStack == NULL)
{
//vista以后的系统来使用
pGetTcpTable = (_InternalGetTcpTable2)GetProcAddress(hIpDLL,"GetTcpTable2");//InternalGetTcpTable2
pGetUdpTable = (_InternalGetUdpTableWithOwnerPid)GetProcAddress(hIpDLL,"InternalGetUdpTableWithOwnerPid");
}
//使用pAllocateAndGetTcpExTableFromStack和pAllocateAndGetUdpExTableFromStack调用相应函数进行输出
DisplayPort();
//释放库
FreeLibrary(hIpDLL);
WSACleanup();
system("pause");
return 0;
}