#include <fstream> #include <iostream> #include <iomanip> //I/O流控制头文件 #include <WINSOCK2.H> using namespace std; struct eth_header //帧头 { unsigned char eth_dst[6]; unsigned char eth_src[6]; unsigned short upper_pro; //上层协议 0800表示是ip数据包 }; struct ip_header //ip报头 { union { unsigned char version; //版本 unsigned char ihl; //报头长度 }; unsigned char tos; //服务类型 unsigned short total_len; //总长度 unsigned short identifer; //标识 union { unsigned short flags; //标志 unsigned short offset; //片偏移 }; unsigned char TTL; //生存周期 unsigned char protocol; //协议 unsigned short checksum; //头部校验和 unsigned char ip_src[4]; //源ip地址 unsigned char ip_dst[4]; //目的ip地址 unsigned int option; //选项+填充 //数据 }; void main() { int temp[38]; //? why 38? ifstream infile("D:\\data"); //打开文件 int i; for (i=0;i<38;i++) { infile>>hex>>temp[i]; //hex 格式化为十六进制数值数据 输入和输出 } infile.close(); struct eth_header eth; struct ip_header ip; for (i=0;i<6;i++) { eth.eth_dst[i]=(unsigned char)temp[i]; } for (i=6;i<12;i++) { eth.eth_src[i-6]=(unsigned char)temp[i]; } eth.upper_pro = (temp[12]<<8)|temp[13]; //? why 左移8位 //以下给ip头部变量赋值 ip.version = (unsigned char)temp[14]; ip.tos = (unsigned char)temp[15]; ip.total_len=(temp[16]<<8)|temp[17]; ip.identifer = (temp[18]<<8)|temp[19]; ip.flags = (unsigned short)(temp[20]<<8)|(temp[21]); ip.TTL = (unsigned char)temp[22]; ip.protocol = (unsigned char)temp[23]; ip.checksum = (temp[24]<<8)|temp[25]; for (i=26;i<30;i++) { ip.ip_src[i-26]=(unsigned char)temp[i]; } for (i=30;i<34;i++) { ip.ip_dst[i-30]=(unsigned char)temp[i]; } //以下输出mac头部信息 cout<<"输出mac帧头部信息(十六进制):"<<endl; cout<<"目的mac地址为:"; for (i=0;i<5;i++) { //setfill是设置填充字符,setw设置输出的宽度,它们的作用表现在紧接着输入的字符串上 cout<<setfill('0')<<setw(2)<<hex<<(int)eth.eth_dst[i]<<"-";//空的地方填充0,宽度为2 } cout<<setfill('0')<<setw(2)<<hex<<(int)eth.eth_dst[5]<<endl; cout<<"源mac地址为:"; for (i=0;i<5;i++) { cout<<setfill('0')<<setw(2)<<hex<<(int)eth.eth_src[i]<<"-"; } cout<<setfill('0')<<setw(2)<<hex<<(int)eth.eth_src[5]<<endl; cout<<"上层协议类型为:"; cout<<setfill('0')<<setw(4)<<hex<<eth.upper_pro<<endl; cout<<"-----------------------------"<<endl; //以下输出ip头部信息 cout<<"输出ip头部信息(十进制):"<<endl; cout<<"版本:"<<dec<<(ip.version>>4)<<endl; //dec十进制 oct八进制 hex十六进制 ip.ihl=ip.version&0x0f; cout<<"ip头部长度(ihl):"<<(ip.ihl*4)<<endl; cout<<"服务类型:"<<(int)ip.tos<<"("<<"优先权子字段" <<(ip.tos>>5)<<"tos子字段:"<<((ip.tos>>1)&0x0f)<<")"<<endl; cout<<"总长度:"<<(int)ip.total_len<<endl; cout<<"标识符:"<<(int)ip.identifer<<endl; cout<<"片偏移:"<<(ip.offset&0x1fff)<<endl; cout<<"生存期:"<<(int)ip.TTL<<endl; cout<<"协议:"<<(int)ip.protocol<<endl; cout<<"首部检校和:"<<(int)ip.checksum<<endl; cout<<"源ip地址:"; for(i=0;i<3;i++) { cout<<(int)ip.ip_src[i]<<"."; } cout<<(int)ip.ip_src[3]<<endl; cout<<"目的ip地址:"; for (i=0;i<3;i++) { cout<<(int)ip.ip_dst[i]<<"."; } cout<<(int)ip.ip_dst[3]<<endl; //以下验证有没有选项字段 if (ip.ihl==5) { cout<<"没有选项字段"<<endl; for (i=34;i<38;i++) { temp[i]=0; } } else { ip.option=(unsigned int)(temp[34]<<24)|(temp[35]<<16)|(temp[36]<<8)|temp[37]; cout<<"选项:"<<(int)ip.option<<endl;//如果有选项字段 将选项和填充一起输出 } cout<<"-----------------------------"<<endl; //以下验证ip数据包头部的正确性 unsigned short m1,m2,sum; unsigned int sum1=0; for (i=14;i<38;i=i+2) { m1 = (unsigned short)(temp[i]<<8); m2 = (unsigned short)temp[i+1]; sum = m1|m2; sum1+=sum; } sum1 = (sum1>>16)+(sum1&0xffff); //oxffff截掉进位那一位 sum1 = (sum1>>16)+(sum1&0xffff); sum1 = (unsigned short)~sum1; if (sum1==0) { cout<<"ip数据包是正确的"<<endl; } else { cout<<"ip数据包是错误的"<<endl; } cout<<"-----------------------------"<<endl; cin.get(); }