1 // CaptureData.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <WinSock2.h> 6 #include <filesystem> 7 #include <mstcpip.h>//SIO_RCVALL头文件 8 9 #pragma comment(lib,"WS2_32.lib")//加载%system32 目录下的ws2_32.dll 10 #define OK 0 11 #define ERR -1 12 13 #define HOST_NAME_MAX 100 14 #define MY_PORT 10000//大于1024,,以下的端口大部分被系统占用 15 #define BUFF_LEN 65536//为啥是6结尾呢, 16 17 //收到的包,是网络字节序(大字节序) 18 typedef struct IP_HEADER 19 { 20 char cVer : 4;//位域,char占8个比特位,这只要4个位的意思 21 char cHeadLen : 4; 22 char cTos; 23 unsigned short usLen; 24 unsigned short usIdent; 25 unsigned short usFlag : 3; 26 unsigned short usOffset : 13; 27 char cTTL; 28 char cProtocol;//用的什么协议 29 unsigned short usChkSum; 30 unsigned int uiSrcIp; 31 unsigned int uiDstIp; 32 }IP_HEADER_S; 33 34 void PrintData(char szBuf[], int iLen) 35 { 36 //printf("RCV:%s\n", szBuf); 37 //打印16进制数据,可以看到内存是怎么存的,每个比特位是什么可以更清楚 38 int i; 39 IP_HEADER_S *pstHeader; 40 SOCKADDR_IN stAddr = {}; 41 pstHeader = (IP_HEADER_S*)szBuf; 42 43 //只要什么包的意思,可以试试自己ping自己,能看到4进4出的数据 44 if (pstHeader->cProtocol != IPPROTO_ICMP)return; 45 46 printf("RCV:"); 47 printf("Version:%d\n", pstHeader->cVer); 48 printf("HeaderLen:%d\n", pstHeader->cHeadLen); 49 printf("DataLen:%d\n", ntohs(pstHeader->usLen));//网络包的int转换 50 printf("TTL:%d\n", pstHeader->cTTL); 51 printf("FLAG_OFFSET:[%d,%d]\n", pstHeader->usFlag, pstHeader->usOffset); 52 printf("Protocol:%d\n", pstHeader->cProtocol); 53 54 stAddr.sin_addr.s_addr = pstHeader->uiSrcIp; 55 //inet_ntoa()//把in_addr转成字符串IP 56 printf("Source IP:%s\n", inet_ntoa(stAddr.sin_addr)); 57 58 stAddr.sin_addr.s_addr = pstHeader->uiDstIp; 59 printf("Dest IP:%s\n", inet_ntoa(stAddr.sin_addr)); 60 61 //for (i = 0; i < iLen; ++i) 62 //{ 63 // //一个字节的字符,asc范围是0x0 到 0xff 64 // printf("%x02x ", szBuf[i] & 0xff); 65 //} 66 67 printf("\n"); 68 } 69 70 int CaptureData() 71 { 72 WSADATA stWsa; 73 char szHostName[HOST_NAME_MAX] = {}; 74 HOSTENT *pHost; 75 SOCKADDR_IN strAddr = { 0 };//抓包地址 76 SOCKET iFd; 77 int iRet; 78 DWORD dwInBuff = 1; 79 DWORD dwOutBuff; 80 DWORD dwRet; 81 char szBuf[BUFF_LEN] = { 0 }; 82 83 //0x0202表示动态链接库的版本号 84 if (WSAStartup(0x0202, &stWsa) != OK)//打开动态链接库,使网络函数可用 85 { 86 return ERR; 87 } 88 89 //获取自己的ip地址,抓包发到这个ip地址的包 90 //1获取主机名,2通过主机名获取ip 91 if (gethostname(szHostName, HOST_NAME_MAX) != OK) 92 { 93 WSACleanup(); 94 return ERR; 95 } 96 97 pHost = gethostbyname(szHostName); 98 99 printf("MYIP:%d.%d.%d.%d\n", pHost->h_addr_list[0][0] & 0xff, pHost->h_addr_list[0][1] & 0xff, pHost->h_addr_list[0][2] & 0xff, pHost->h_addr_list[0][3] & 0xff);//& 0xff的作用对ip地址转%d的int后的前面部分无用字节去掉 100 101 strAddr.sin_family = AF_INET; 102 strAddr.sin_addr.s_addr = *(unsigned long*)pHost->h_addr;//对字符数字强制转换 103 strAddr.sin_port = htons(MY_PORT); 104 105 //SOCK_RAW 抓取底层数据包(原始数据流) 106 iFd = socket(AF_INET, SOCK_RAW, IPPROTO_IP); 107 if (iFd < 0) 108 { 109 WSACleanup(); 110 return ERR; 111 } 112 113 if (bind(iFd, (SOCKADDR*)&strAddr, sizeof(SOCKADDR)) != OK) 114 { 115 WSACleanup(); 116 closesocket(iFd); 117 return ERR; 118 } 119 120 //定义收包的规则 121 iRet = WSAIoctl(iFd, SIO_RCVALL, &dwInBuff, sizeof(dwInBuff), &dwOutBuff, sizeof(dwOutBuff), &dwRet, NULL, NULL); 122 if (iRet != OK) 123 { 124 WSACleanup(); 125 closesocket(iFd); 126 return ERR; 127 } 128 129 while (true) 130 { 131 memset(szBuf, 0, BUFF_LEN); 132 133 iRet = recv(iFd, szBuf, BUFF_LEN, 0);//返回接收数据的长度 134 if (iRet < 0) 135 { 136 break; 137 } 138 else 139 { 140 PrintData(szBuf, iRet); 141 } 142 } 143 144 145 146 closesocket(iFd); 147 WSACleanup(); 148 return 0; 149 } 150 151 int _tmain(int argc, _TCHAR* argv[]) 152 { 153 CaptureData(); 154 system("pause"); 155 return 0; 156 }
时间: 2024-10-12 00:07:27