您的位置:首页 > 理论基础 > 计算机网络

VC++实现获取所有的TCP与UDP链接

2012-09-04 16:57 357 查看
我们亲自来实现获取所有的TCP与UDP的网络链接。

/*

定义协议格式
定义协议中使用的宏

*/

#ifndef__PROTOINFO_H__
#define__PROTOINFO_H__

#defineETHERTYPE_IP0x0800
#defineETHERTYPE_ARP0x0806

typedefstruct_ETHeader//14字节的以太头
{
UCHARdhost[6];//目的MAC地址destinationmacaddress
UCHARshost[6];//源MAC地址sourcemacaddress
USHORTtype;//下层协议类型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等
}ETHeader,*PETHeader;

#defineARPHRD_ETHER1

//ARP协议opcodes
#defineARPOP_REQUEST1//ARP请求
#defineARPOP_REPLY2//ARP响应

typedefstruct_ARPHeader//28字节的ARP头
{
USHORThrd;//硬件地址空间,以太网中为ARPHRD_ETHER
USHORTeth_type;//以太网类型,ETHERTYPE_IP??
UCHARmaclen;//MAC地址的长度,为6
UCHARiplen;//IP地址的长度,为4
USHORTopcode;//操作代码,ARPOP_REQUEST为请求,ARPOP_REPLY为响应
UCHARsmac[6];//源MAC地址
UCHARsaddr[4];//源IP地址
UCHARdmac[6];//目的MAC地址
UCHARdaddr[4];//目的IP地址
}ARPHeader,*PARPHeader;

//协议
#definePROTO_ICMP1
#definePROTO_IGMP2
#definePROTO_TCP6
#definePROTO_UDP17

typedefstruct_IPHeader//20字节的IP头
{
UCHARiphVerLen;//版本号和头长度(各占4位)
UCHARipTOS;//服务类型
USHORTipLength;//封包总长度,即整个IP报的长度
USHORTipID;//封包标识,惟一标识发送的每一个数据报
USHORTipFlags;//标志
UCHARipTTL;//生存时间,就是TTL
UCHARipProtocol;//协议,可能是TCP、UDP、ICMP等
USHORTipChecksum;//校验和
ULONGipSource;//源IP地址
ULONGipDestination;//目标IP地址
}IPHeader,*PIPHeader;

//定义TCP标志
#defineTCP_FIN0x01
#defineTCP_SYN0x02
#defineTCP_RST0x04
#defineTCP_PSH0x08
#defineTCP_ACK0x10
#defineTCP_URG0x20
#defineTCP_ACE0x40
#defineTCP_CWR0x80

typedefstruct_TCPHeader//20字节的TCP头
{
USHORTsourcePort;//16位源端口号
USHORTdestinationPort;//16位目的端口号
ULONGsequenceNumber;//32位序列号
ULONGacknowledgeNumber;//32位确认号
UCHARdataoffset;//高4位表示数据偏移
UCHARflags;//6位标志位
//FIN-0x01
//SYN-0x02
//RST-0x04
//PUSH-0x08
//ACK-0x10
//URG-0x20
//ACE-0x40
//CWR-0x80

USHORTwindows;//16位窗口大小
USHORTchecksum;//16位校验和
USHORTurgentPointer;//16位紧急数据偏移量
}TCPHeader,*PTCPHeader;

typedefstruct_UDPHeader
{
USHORTsourcePort;//源端口号
USHORTdestinationPort;//目的端口号
USHORTlen;//封包长度
USHORTchecksum;//校验和
}UDPHeader,*PUDPHeader;

#endif//__PROTOINFO_H__

#include<stdio.h>
#include<windows.h>
#include<Iphlpapi.h>

#pragmacomment(lib,"Iphlpapi.lib")
#pragmacomment(lib,"WS2_32.lib")

PMIB_TCPTABLEMyGetTcpTable(BOOLbOrder);
PMIB_UDPTABLEMyGetUdpTable(BOOLbOrder);

voidMyFreeTcpTable(PMIB_TCPTABLEpTcpTable);
voidMyFreeUdpTable(PMIB_UDPTABLEpUdpTable);

intmain()
{
//打印TCP连接表信息
PMIB_TCPTABLEpTcpTable=MyGetTcpTable(TRUE);
if(pTcpTable!=NULL)
{
charstrState[128];
structin_addrinadLocal,inadRemote;
DWORDdwRemotePort=0;
charszLocalIp[128];
charszRemIp[128];

printf("TCPTABLE\n");
printf("%20s%10s%20s%10s%s\n","LocAddr","LocPort","RemAddr",
"RemPort","State");
for(UINTi=0;i<pTcpTable->dwNumEntries;++i)
{
//状态
switch(pTcpTable->table[i].dwState)
{
caseMIB_TCP_STATE_CLOSED:
strcpy(strState,"CLOSED");
break;
caseMIB_TCP_STATE_TIME_WAIT:
strcpy(strState,"TIME_WAIT");
break;
caseMIB_TCP_STATE_LAST_ACK:
strcpy(strState,"LAST_ACK");
break;
caseMIB_TCP_STATE_CLOSING:
strcpy(strState,"CLOSING");
break;
caseMIB_TCP_STATE_CLOSE_WAIT:
strcpy(strState,"CLOSE_WAIT");
break;
caseMIB_TCP_STATE_FIN_WAIT1:
strcpy(strState,"FIN_WAIT1");
break;
caseMIB_TCP_STATE_ESTAB:
strcpy(strState,"ESTAB");
break;
caseMIB_TCP_STATE_SYN_RCVD:
strcpy(strState,"SYN_RCVD");
break;
caseMIB_TCP_STATE_SYN_SENT:
strcpy(strState,"SYN_SENT");
break;
caseMIB_TCP_STATE_LISTEN:
strcpy(strState,"LISTEN");
break;
caseMIB_TCP_STATE_DELETE_TCB:
strcpy(strState,"DELETE");
break;
default:
printf("Error:unknownstate!\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((unsignedshort)(0x0000FFFF&pTcpTable->table[i].dwLocalPort)),
szRemIp,ntohs((unsignedshort)(0x0000FFFF&dwRemotePort)),
strState);
}
MyFreeTcpTable(pTcpTable);
}

printf("\n\n");

//打印UDP监听表信息
PMIB_UDPTABLEpUdpTable=MyGetUdpTable(TRUE);
if(pUdpTable!=NULL)
{
structin_addrinadLocal;
printf("UDPTABLE\n");

printf("%20s%10s\n","LocAddr","LocPort");
for(UINTi=0;i<pUdpTable->dwNumEntries;++i)
{
inadLocal.s_addr=pUdpTable->table[i].dwLocalAddr;
//打印出此入口的信息
printf("%20s%10u\n",
inet_ntoa(inadLocal),ntohs((unsignedshort)(0x0000FFFF&pUdpTable->table[i].dwLocalPort)));
}

MyFreeUdpTable(pUdpTable);
}

return0;
}

PMIB_TCPTABLEMyGetTcpTable(BOOLbOrder)
{
PMIB_TCPTABLEpTcpTable=NULL;
DWORDdwActualSize=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)
returnpTcpTable;
::GlobalFree(pTcpTable);
}
returnNULL;
}

voidMyFreeTcpTable(PMIB_TCPTABLEpTcpTable)
{
if(pTcpTable!=NULL)
::GlobalFree(pTcpTable);
}

PMIB_UDPTABLEMyGetUdpTable(BOOLbOrder)
{
PMIB_UDPTABLEpUdpTable=NULL;
DWORDdwActualSize=0;

//查询所需缓冲区的大小
if(::GetUdpTable(pUdpTable,&dwActualSize,bOrder)==ERROR_INSUFFICIENT_BUFFER)
{
//为MIB_UDPTABLE结构申请内存
pUdpTable=(PMIB_UDPTABLE)::GlobalAlloc(GPTR,dwActualSize);
//获取UDP监听表
if(::GetUdpTable(pUdpTable,&dwActualSize,bOrder)==NO_ERROR)
returnpUdpTable;
::GlobalFree(pUdpTable);
}
returnNULL;
}

voidMyFreeUdpTable(PMIB_UDPTABLEpUdpTable)
{
if(pUdpTable!=NULL)
::GlobalFree(pUdpTable);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: