所谓抓包,就是获取所有从本机电脑中传输过的网络数据包。
目录
网络的协议
1 以太网头
typedef struct HeadEth {
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
unsigned short h_proto;
}HEADETH, * PHEADETH;
以太网头表明了此包的源地址,目的地址与协议类型(IPv4等)
2 IP头
typedef struct HeadIP {
unsigned char headerlen : 4;
unsigned char version : 4;
unsigned char servertype;
unsigned short totallen;
unsigned short id;
unsigned short idoff;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;
}HEADIP, *PHEADIP;
IP头记录着包的所有信息(除端口号),其中比较重要的就是sourceIP与destIP。
3 TCP头
typedef struct HeadTCP {
WORD SourcePort;
WORD DePort;
DWORD SequenceNo;
DWORD ConfirmNo;
BYTE HeadLen;
BYTE Flag;
WORD WndSize;
WORD CheckSum;
WORD UrgPtr;
}HEADTCP, * PHEADTCP;
TCP头属于IP头的扩展头,记录着发送端端口与接收端端口,以及头长度,还有校验和。
4 UDP头
typedef struct HeadUDP {
WORD SourcePort;
WORD DePort;
WORD Len;
WORD ChkSum;
}HEADUDP, * PHEADUDP;
UDP头基本上与TCP头差不多。
抓包的原理
- 确定抓包的IP地址
- 绑定与设置套接字接受命令
- 接受数据
- 分析数据
- 输出
抓包关键函数
凡是网络通信,都需要用到Socket,
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
1 设置套接字接受命令 WSAIoctl函数详解
int iResult = WSAIoctl(SnifferSocket, SIO_RCVALL, &Optval, sizeof(Optval), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL);
if (SOCKET_ERROR == iResult)
{
cout << "套接字设置失败:" << WSAGetLastError() << endl;
closesocket(SnifferSocket);
WSACleanup();
return 1;
}
2 网络字节顺序转本机字节顺序
ntohs(unsigned short us)
//return type<unsigned short>
3 获取IP头
HeadIP* pIpInfo = (HeadIP*)recvbuf;