#define BUFFER_SIZE 65535
char buffer[BUFFER_SIZE]; //设置缓冲区 while(true) {
recv(sock,buffer,BUFFER_SIZE,0); //接收数据包 /*然后是解析接收的IP包*/ }
3、定义IP头部的数据结构
程序需要定义一个数据结构表示IP头部。这个数据结构应该和IP数据包的格式吻合,其代码如下:
typedef struct _IP_HEADER //定义IP头 {
union {
BYTE Version; //版本(前4位) BYTE HdrLen; //报头标长(后4位),IP头的长度 };
BYTE ServiceType; //服务类型 WORD TotalLen; //总长度 WORD ID; //标识 union {
WORD Flags; //标志(前3位)
WORD FragOff; //分段偏移(后13位) };
BYTE TimeToLive; //生命期 BYTE Protocol; //协议 WORD HdrChksum; //头校验和 DWORD SrcAddr; //源地址 DWORD DstAddr; //目的地址 BYTE Options; //选项 } IP_HEADER;
这里只考虑IP头部结构,不考虑数据部分。在捕获IP数据包后,可以通过指针把缓冲区的内容强制转化为IP_HEADER的数据结构。
IP_HEADER ip=*(IP_HEADER*)buffer; 4、IP包的解析
通过IP_HEADER解析IP头各个字段的代码: /*获取版本字段*/ ip.Version>>4;
/*获取头部长度字段*/ ip.HdrLen & 0x0f;
/*获取服务类型字段中的优先级子域*/ ip.ServiceType>>5;
/*获取服务类型字段中的TOS子域*/
(ip.ServiceType>>1)&0x0f; /*获取总长度字段*/ ip.TotalLen; /*获取标识字段*/ ip.ID;
/*解析标志字段*/
DF = (ip.Flags>>14) & 0x01; MF = (ip.Flags>>13) & 0x01; /*获取分段偏移字段*/ ip.FragOff & 0x1fff; /*获取生存时间字段*/ ip.TimeToLive; /*获取协议字段*/ ip.Protocol;
/*获取头校验和字段*/ ip.HdrChksum;
/*解析源IP地址字段*/
inet_ntoa(*(in_addr*)&ip.SrcAddr); /*解析目的IP地址字段*/
inet_ntoa(*(in_addr*)&ip.DstAddr);