真的很简易,这个程序仅仅是抓一些发送到本机的数据包,然后显示出来它们的一些信息罢了!
程序非常简单!
#include <WinSock2.h> #include <windows.h> #include <stdio.h> #include <stdlib.h> #pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/ #define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1) const int MAX_ADDR_LEN = 16; /*ip地址长度*/ const int MAX_HOSTNAME_LEN = 255; /*主机名称*/ /*WORD 16位 DWORD 32位*/ struct IPHeader { BYTE HeaderLength : 4; //首部长度 BYTE Version : 4; //版本 BYTE DS; //区分服务 WORD TotalLength; //总长度 WORD ID; //标识 BYTE FragmentOffset0 : 5; //片偏移 BYTE MF : 1; //MF标识 BYTE DF : 1; //DF标识 BYTE Reserved : 1; //保留标识 BYTE FragmentOffset1; //片偏移 BYTE TTL; //生存时间 BYTE Protocol; //协议 WORD Checksum; //检验和 DWORD SourceAddress; //源地址 DWORD DestinationAddress; //目的地址 }; struct TCPHeader { WORD SourcePort; //源端口 WORD DestinationPort; //目的端口 DWORD SequenceNumber; //序号 DWORD AcknowledgmentNumber; //确认号 BYTE Reserved0 : 4; //保留字段第一部分 BYTE DataOffset : 4; //数据偏移 BYTE FIN : 1; //FIN标识 BYTE SYN : 1; //SYN标识 BYTE RST : 1; //RST标识 BYTE PSH : 1; //PSH标识 BYTE ACK : 1; //ACK标识 BYTE URG : 1; //URG标识 BYTE Reserved1 : 2; //保留字段第二部分 WORD Window; //窗口 WORD Checksum; //检验和 WORD UrgentPointer; //紧急指针 }; struct UDPHeader { WORD SourcePort; //源端口 WORD DestinationPort; //目的端口 WORD Length; //长度 WORD Checksum; //检验和 }; void main() { SOCKET sock; WSADATA wsd; DWORD dwBytesRet; unsigned int optval = 1; int pCount = 0; sockaddr_in source, dest; char hostName[MAX_HOSTNAME_LEN]; char sourceIP[MAX_ADDR_LEN]; /*记录源ip地址*/ char destIP[MAX_ADDR_LEN]; /*记录目的ip地址*/ char recvBuff[65535] = { 0 }; WSAStartup(MAKEWORD(2, 1), &wsd); /*初始化*/ hostent *pHostent; UDPHeader *pUdpheader; /*UDP头部*/ IPHeader *pIpheader; /*IP头部*/ TCPHeader *pTcpheader; /*TCP头部*/ if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == SOCKET_ERROR)/*创建原始套接字*/ { exit(-1); } gethostname(hostName, MAX_HOSTNAME_LEN); //获取主机名称 pHostent = gethostbyname(hostName); //获取有关于本机信息的一个hostent结构体 sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); /*绑定套接字*/ if (WSAGetLastError() == 10013) { exit(1); } /************************************************************************/ /* The WSAIoctl function controls the mode of a socket. */ /************************************************************************/ /*这个函数主要用来设定一些参数,这里设定接收所有的数据包*/ WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); pIpheader = (IPHeader *)recvBuff; while (pCount < 1000) { memset(recvBuff, 0, sizeof(recvBuff)); recv(sock, recvBuff, sizeof(recvBuff), 0); /*接收数据包*/ source.sin_addr.S_un.S_addr = pIpheader->SourceAddress; /*数据包源地址*/ strncpy_s(sourceIP, inet_ntoa(source.sin_addr), MAX_ADDR_LEN); dest.sin_addr.S_un.S_addr = pIpheader->DestinationAddress; /*目的地址*/ strncpy_s(destIP, inet_ntoa(dest.sin_addr), MAX_ADDR_LEN); if (pIpheader->Protocol == IPPROTO_TCP) /*使用的是TCP协议*/ { int dataLen; pTcpheader = (TCPHeader *)(recvBuff + sizeof(IPHeader)); dataLen = (pIpheader->TotalLength - (pIpheader->HeaderLength * 4 + pTcpheader->DataOffset * 4));//tcp可能存在扩展 if (dataLen == 0) break; printf("---------------------TCP---------------------\n"); printf("数据包序号 : %d\n", pCount); printf("数据包大小 : %d\n", dataLen); printf("源IP地址 :%s\n", sourceIP); /*ntohs(s表示short)即将16位的数从网络(network)字节序转换为主机(host)字节序*/ /*同理,ntohl(l表示long)即将32位的数从网络(network)字节序转换为主机(host)字节序*/ printf("源端口 :%d\n", ntohs(pTcpheader->SourcePort)); printf("目地ip地址 :%s\n", destIP); printf("目的端口 :%d\n", ntohs(pTcpheader->DestinationPort)); printf(" IP头部大小:%d\n", pIpheader->HeaderLength * 4); printf("TCP头部大小:%d\n", (pTcpheader->DataOffset) * 4); Sleep(1000);/*如果不休眠一下的话,速度会非常的快!*/ pCount++; } if (pIpheader->Protocol == IPPROTO_UDP) //数据包使用UDP { pUdpheader = (UDPHeader *)(recvBuff + sizeof(IPHeader)); int dataLen; dataLen = (pIpheader->TotalLength - (pIpheader->HeaderLength * 4 + sizeof(UDPHeader)));//udp首部并没有扩展 if (dataLen == 0) break; printf("---------------------UDP--------------------\n"); printf("数据包序号 : %d\n", pCount); printf("数据包大小 : %d\n", dataLen); printf("源IP地址 :%s\n", sourceIP); printf("源端口 :%d\n", ntohs(pUdpheader->SourcePort)); printf("目的IP地址 :%s\n", destIP); printf("目的端口 :%d\n", ntohs(pUdpheader->DestinationPort)); printf("IP头部大小 :%d\n", (pIpheader->HeaderLength)* 4); printf("UDP头部大小:%d\n", sizeof(UDPHeader)); Sleep(1000);//如果不休眠一下的话,速度会非常的快! pCount++; } }/*while*/ system("pause"); }