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

来源:互联网 发布:天猫魔盒直播软件 编辑:程序博客网 时间:2024/04/30 14:59

 

我们亲自来实现获取所有的TCP与UDP的网络链接。

 

 

/*

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

 */

#ifndef __PROTOINFO_H__#define __PROTOINFO_H__

#define ETHERTYPE_IP    0x0800#define ETHERTYPE_ARP   0x0806

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;

#define ARPHRD_ETHER  1

// ARP协议opcodes#define ARPOP_REQUEST 1  // ARP 请求 #define ARPOP_REPLY  2  // ARP 响应

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;

// 协议#define PROTO_ICMP    1#define PROTO_IGMP    2#define PROTO_TCP     6#define PROTO_UDP     17

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;

// 定义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

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

 USHORT windows;   // 16位窗口大小 USHORT checksum;   // 16位校验和 USHORT urgentPointer;  // 16位紧急数据偏移量 } TCPHeader, *PTCPHeader;

typedef struct _UDPHeader{ USHORT   sourcePort;  // 源端口号   USHORT   destinationPort;// 目的端口号   USHORT   len;   // 封包长度 USHORT   checksum;  // 校验和} UDPHeader, *PUDPHeader;

#endif // __PROTOINFO_H__

#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;}elsedwRemotePort = 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结构申请内存 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);}