tcpview的工作原理
通过使用用iphlapi库里的函数来获取网络信息。
如针对tcp, 3个函数( GetExtendedTcpTable / AllocateAndGetTcpExTableFromStack / GetTcpTable ),有哪个用哪个,函数底层基本一样
// 下面的测试例子通过GetExtendedTcpTable获取tcp信息, 如要获取udp方法差不多,函数为GetExtendedUdpTable
#include <stdio.h>
#include <windows.h>
#include "Iphlpapi.h"
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment(lib,"ws2_32.lib")
int main()
{
PMIB_TCPTABLE_OWNER_MODULE pTcpTable(NULL);
DWORD dwSize(0);
// 第一次调用,目的去获取要分配的内存大小,dwSize
if(GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) == ERROR_INSUFFICIENT_BUFFER)
pTcpTable = (MIB_TCPTABLE_OWNER_PID*)new char[dwSize];//重新分配缓冲区
// 第一次获取数据
if (GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) != NO_ERROR)
{
delete pTcpTable;
return 0;
}
int nNum = (int)pTcpTable->dwNumEntries; //TCP连接的数目
for (int i = 0; i < nNum; i++)
{
printf("本地地址:%s:%d ",
inet_ntoa(*(in_addr*)&pTcpTable->table[i].dwLocalAddr), //本地IP 地址
htons(pTcpTable->table[i].dwLocalPort)); //本地端口
printf(" 远程地址:%s:%d ",inet_ntoa(*(in_addr*)&pTcpTable->table[i].dwRemoteAddr), //远程IP地址
htons(pTcpTable->table[i].dwRemotePort) ); //远程端口
printf("状态:%d 进程ID:%d\n",
pTcpTable->table[i].dwState, //状态
pTcpTable->table[i].dwOwningPid); //所属进程PID ,
}
delete pTcpTable;
return 1;
}
1. 关于状态pTcpTable->table[i].dwState, 参照https://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcprow_owner_module
主要的如,MIB_TCP_STATE_LISTEN == 2 , MIB_TCP_STATE_ESTAB == 5
2. 有了进程id pTcpTable->table[i].dwOwningPid, 通过CreateToolhelp32Snapshot等函数找到对应的进程名及更多相关信息
3. 函数底层实现是通过NtDeviceIoControlFile给设备对象发送irp包,win10下为("\Device\Nsi" 本质还是发送到\Device\Tcp和\Device\Udp,Nsi只是个接口)或者
xp下(\Device\tcp和\Device\udp)。 这是windows系统的特点,不管你想干点什么最后永远都是发送irp包。
参考:

浙公网安备 33010602011771号