转载请注明出处:http://blog.csdn.net/drecik__/article/details/8071902
因为要自己分析包内容,所以首先得自己定义IP头结构体和其他协议头(当然不能随便定义,要按照它要求的格式)
定义IP头:
// 20字节的IP头;
typedef struct _IP_HEADER
{
UCHAR iphVerLen; // 版本号和长度(各四位);
UCHAR iphTOS; // 服务类型;
USHORT iphLength; // 封包总长度;
USHORT iphID; // 封包标识;
USHORT iphFlags; // 标志;
UCHAR iphTTL; // 生存时间;
UCHAR iphProtocol; // 协议类型;
USHORT iphCheckSum; // 校验和;
ULONG iphSource; // 源IP地址;
ULONG iphDest; // 目标IP地址;
} IP_HEADER, *PIP_HEADER;
定义协议头,这里只有TCP头和UCP头:
// 8个字节的UDP头;
typedef struct _UCP_HEADER
{
USHORT udphSourcePort; // 源端口号;
USHORT udphDestPort; // 目标端口号;
USHORT udphLength; // 封包长度;
USHORT udphCheckSum; // 校验和;
} UDP_HEADER, *PUDP_HEADER;
// 20个字节的TCP头;
typedef struct _TCP_HEADER
{
USHORT tcphSourctPort; // 源端口号;
USHORT tcphDestPort; // 目标端口号;
ULONG tcphSeqNumber; // 序列号;
ULONG tcphAckNumber; // 确认号;
UCHAR tcphDataOffset; // 4位首部长度/6位保留字;
UCHAR tcphFlags; // 6位标志;
USHORT tcphWindow; // 窗口大小;
USHORT tcphCheckSum; // 校验和;
USHORT tcphUrgentPt; // 紧急数据偏移量;
} TCP_HEADER, *PTCP_HEADER;
创建原始套接字,绑定到本地IP(这个一定要),并设置接收所有包
// 创建原始套接字;
SOCKET s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
// 获得用户名;
char szHostName[32];
gethostname(szHostName, sizeof(szHostName));
// 获得本地IP地址;
hostent* pHost;
pHost = gethostbyname(szHostName);
SOCKADDR_IN sin;
sin.sin_family = AF_INET;
sin.sin_port = 0;
memcpy( &sin.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length );
printf( "绑定到IP:%s", inet_ntoa(sin.sin_addr) );
bind( s, (LPSOCKADDR)&sin, sizeof(sin) );
// 设置接受所有包;
DWORD dwValue = 1;
ioctlsocket( s, SIO_RCVALL, &dwValue );
然后接收数据
char buf[1024*10];
int iRet;
while ( TRUE )
{
iRet = recv(s, buf, 1024*10, 0);
if ( iRet > 0 )
{
// 解析IP包;
DecodeIPPacket(buf);
// Sleep(3000);
}
}
解析封包的时候就是利用所定义的IP头和各种协议头来分析
具体可以下载代码来查看 网址: http://download.csdn.net/detail/drecik__/4647617