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 }

 

posted on 2015-10-19 18:07  俗剑仙·情如梦  阅读(640)  评论(0编辑  收藏  举报