VC++实现获取所有的TCP与UDP链接
来源:岁月联盟
时间:2012-09-04
[cpp]
[cpp]
<p>/*</p><p>定义协议格式
定义协议中使用的宏</p><p> */</p><p>
#ifndef __PROTOINFO_H__
#define __PROTOINFO_H__</p><p>
#define ETHERTYPE_IP 0x0800
#define ETHERTYPE_ARP 0x0806</p><p>typedef struct _ETHeader // 14字节的以太头
{
UCHAR dhost[6]; // 目的MAC地址destination mac address
UCHAR shost[6]; // 源MAC地址source mac address
USHORT type; // 下层协议类型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等
} ETHeader, *PETHeader;</p><p>
#define ARPHRD_ETHER 1</p><p>// ARP协议opcodes
#define ARPOP_REQUEST 1 // ARP 请求
#define ARPOP_REPLY 2 // ARP 响应</p><p>
typedef struct _ARPHeader // 28字节的ARP头
{
USHORT hrd; // 硬件地址空间,以太网中为ARPHRD_ETHER
USHORT eth_type; // 以太网类型,ETHERTYPE_IP ??
UCHAR maclen; // MAC地址的长度,为6
UCHAR iplen; // IP地址的长度,为4
USHORT opcode; // 操作代码,ARPOP_REQUEST为请求,ARPOP_REPLY为响应
UCHAR smac[6]; // 源MAC地址
UCHAR saddr[4]; // 源IP地址
UCHAR dmac[6]; // 目的MAC地址
UCHAR daddr[4]; // 目的IP地址
} ARPHeader, *PARPHeader;</p><p>
// 协议
#define PROTO_ICMP 1
#define PROTO_IGMP 2
#define PROTO_TCP 6
#define PROTO_UDP 17</p><p>typedef struct _IPHeader // 20字节的IP头
{
UCHAR iphVerLen; // 版本号和头长度(各占4位)
UCHAR ipTOS; // 服务类型
USHORT ipLength; // 封包总长度,即整个IP报的长度
USHORT ipID; // 封包标识,惟一标识发送的每一个数据报
USHORT ipFlags; // 标志
UCHAR ipTTL; // 生存时间,就是TTL
UCHAR ipProtocol; // 协议,可能是TCP、UDP、ICMP等
USHORT ipChecksum; // 校验和
ULONG ipSource; // 源IP地址
ULONG ipDestination; // 目标IP地址
} IPHeader, *PIPHeader; </p><p>
// 定义TCP标志
#define TCP_FIN 0x01
#define TCP_SYN 0x02
#define TCP_RST 0x04
#define TCP_PSH 0x08
#define TCP_ACK 0x10
#define TCP_URG 0x20
#define TCP_ACE 0x40
#define TCP_CWR 0x80</p><p>typedef struct _TCPHeader // 20字节的TCP头
{
USHORT sourcePort; // 16位源端口号
USHORT destinationPort; // 16位目的端口号
ULONG sequenceNumber; // 32位序列号
ULONG acknowledgeNumber; // 32位确认号
UCHAR dataoffset; // 高4位表示数据偏移
UCHAR flags; // 6位标志位
//FIN - 0x01
//SYN - 0x02
//RST - 0x04
//PUSH- 0x08
//ACK- 0x10
//URG- 0x20
//ACE- 0x40
//CWR- 0x80</p><p> USHORT windows; // 16位窗口大小
USHORT checksum; // 16位校验和
USHORT urgentPointer; // 16位紧急数据偏移量
} TCPHeader, *PTCPHeader;</p><p>typedef struct _UDPHeader
{
USHORT sourcePort; // 源端口号
USHORT destinationPort;// 目的端口号
USHORT len; // 封包长度
USHORT checksum; // 校验和
} UDPHeader, *PUDPHeader;</p><p>#endif // __PROTOINFO_H__
</p>#include <stdio.h>
#include <windows.h>
#include <Iphlpapi.h>
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "WS2_32.lib")
PMIB_TCPTABLE MyGetTcpTable(BOOL bOrder);
PMIB_UDPTABLE MyGetUdpTable(BOOL bOrder);
void MyFreeTcpTable(PMIB_TCPTABLE pTcpTable);
void MyFreeUdpTable(PMIB_UDPTABLE pUdpTable);
int main()
{
// 打印TCP连接表信息
PMIB_TCPTABLE pTcpTable = MyGetTcpTable(TRUE);
if(pTcpTable != NULL)
{
char strState[128];
struct in_addr inadLocal, inadRemote;
DWORD dwRemotePort = 0;
char szLocalIp[128];
char szRemIp[128];
printf("TCP TABLE/n");
printf("%20s %10s %20s %10s %s/n", "Loc Addr", "Loc Port", "Rem Addr",
"Rem Port", "State");
for(UINT i = 0; i < pTcpTable->dwNumEntries; ++i)
{
// 状态
switch (pTcpTable->table[i].dwState)
{
case MIB_TCP_STATE_CLOSED:
strcpy(strState, "CLOSED");
break;
case MIB_TCP_STATE_TIME_WAIT:
strcpy(strState, "TIME_WAIT");
break;
case MIB_TCP_STATE_LAST_ACK:
strcpy(strState, "LAST_ACK");
break;
case MIB_TCP_STATE_CLOSING:
strcpy(strState, "CLOSING");
break;
case MIB_TCP_STATE_CLOSE_WAIT:
strcpy(strState, "CLOSE_WAIT");
break;
case MIB_TCP_STATE_FIN_WAIT1:
strcpy(strState, "FIN_WAIT1");
break;
case MIB_TCP_STATE_ESTAB:
strcpy(strState, "ESTAB");
break;
case MIB_TCP_STATE_SYN_RCVD:
strcpy(strState, "SYN_RCVD");
break;
case MIB_TCP_STATE_SYN_SENT:
strcpy(strState, "SYN_SENT");
break;
case MIB_TCP_STATE_LISTEN:
strcpy(strState, "LISTEN");
break;
case MIB_TCP_STATE_DELETE_TCB:
strcpy(strState, "DELETE");
break;
default:
printf("Error: unknown state!/n");
break;
}
// 本地地址
inadLocal.s_addr = pTcpTable->table[i].dwLocalAddr;
// 远程端口
if (strcmp(strState, "LISTEN") != 0)
{
dwRemotePort = pTcpTable->table[i].dwRemotePort;
}
else
dwRemotePort = 0;
// 远程IP地址
inadRemote.s_addr = pTcpTable->table[i].dwRemoteAddr;
strcpy(szLocalIp, inet_ntoa(inadLocal));
strcpy(szRemIp, inet_ntoa(inadRemote));
printf("%20s %10u %20s %10u %s/n",
szLocalIp, ntohs((unsigned short)(0x0000FFFF & pTcpTable->table[i].dwLocalPort)),
szRemIp, ntohs((unsigned short)(0x0000FFFF & dwRemotePort)),
strState);
}
MyFreeTcpTable(pTcpTable);
}
printf(" /n/n");
// 打印UDP监听表信息
PMIB_UDPTABLE pUdpTable = MyGetUdpTable(TRUE);
if(pUdpTable != NULL)
{
struct in_addr inadLocal;
printf("UDP TABLE/n");
printf("%20s %10s/n", "Loc Addr", "Loc Port");
for (UINT i = 0; i < pUdpTable->dwNumEntries; ++i)
{
inadLocal.s_addr = pUdpTable->table[i].dwLocalAddr;
// 打印出此入口的信息
printf("%20s %10u /n",
inet_ntoa(inadLocal), ntohs((unsigned short)(0x0000FFFF & pUdpTable->table[i].dwLocalPort)));
}
MyFreeUdpTable(pUdpTable);
}
return 0;
}
PMIB_TCPTABLE MyGetTcpTable(BOOL bOrder)
{
PMIB_TCPTABLE pTcpTable = NULL;
DWORD dwActualSize = 0;
// 查询所需缓冲区的大小
if(::GetTcpTable(pTcpTable, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER)
{
// 为MIB_TCPTABLE结构申请内存
pTcpTable = (PMIB_TCPTABLE)::GlobalAlloc(GPTR, dwActualSize);
// 获取TCP连接表
if(::GetTcpTable(pTcpTable, &dwActualSize, bOrder) == NO_ERROR)
return pTcpTable;
::GlobalFree(pTcpTable);
}
return NULL;
}
void MyFreeTcpTable(PMIB_TCPTABLE pTcpTable)
{
if(pTcpTable != NULL)
::GlobalFree(pTcpTable);
}
PMIB_UDPTABLE MyGetUdpTable(BOOL bOrder)
{
PMIB_UDPTABLE pUdpTable = NULL;
DWORD dwActualSize = 0;
// 查询所需缓冲区的大小
if(::GetUdpTable(pUdpTable, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER)
{
// 为MIB_UDPTABLE结构申请内存 www.2cto.com
pUdpTable = (PMIB_UDPTABLE)::GlobalAlloc(GPTR, dwActualSize);
// 获取UDP监听表
if(::GetUdpTable(pUdpTable, &dwActualSize, bOrder) == NO_ERROR)
return pUdpTable;
::GlobalFree(pUdpTable);
}
return NULL;
}
void MyFreeUdpTable(PMIB_UDPTABLE pUdpTable)
{
if(pUdpTable != NULL)
::GlobalFree(pUdpTable);
}
上一篇:VC++基于LSP拦截数据封包
下一篇:VC++实现获取DNS服务器