IP数据包解析代码.doc
Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-dateIP数据包解析代码#include<stdio.h>#include<stdio.h>#include <iostream.h>#include <Winsock2.h>#include <ws2tcpip.h>#pragma comment (lib,"Ws2_32.lib")#define BUFFER_SIZE 65535#define FRAGMENT_SIZE 10000 /分片数据部分最长为10000#define FRAGMENT_NUM 7#define START 20#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)typedef struct _IP_HEADER /定义IP头BYTE Version_HeadLen; /版本(前4位)和首部长度 BYTE ServiceType; /服务类型WORD TotalLen; /数据报总长WORD ID; /标识WORD Flags_FragOff; /标志(前3位),后13位表示页偏移BYTE TimeToLive; /生存周期BYTE Protocol; /协议WORD HdrChksum; /头校验和DWORD SrcAddr; /源地址DWORD DstAddr; /目地地址IP_HEADER;void checksum(IP_HEADER *ip,WORD *sum)unsigned int sum_tmp;sum_tmp=MAKEWORD(ip->ServiceType,ip->Version_HeadLen)+ip->TotalLen+ip->ID+ip->Flags_FragOff+MAKEWORD(ip->Protocol,ip->TimeToLive)+ip->HdrChksum+(WORD)(ip->SrcAddr>>16)+(WORD)(ip->SrcAddr & 0xffff)+(WORD)(ip->DstAddr>>16)+(WORD)(ip->DstAddr & 0xffff);if(sum_tmp>(216-1)sum_tmp=(unsigned short)sum_tmp+1;*sum=(WORD)(sum_tmp);char * parseServiceType_getProcedence(BYTE b)switch(b>>5)/获取服务类型字段中优先级子域case 7: return "Network Control"/网络控制break;case 6:return "Internet work Control" /网络控制break;case 5:return "CRITIC/ECP" break;case 4:return "Flash Override"/最优先信号break;case 3:return "Flsah" break;case 2:return "Immediate" break;case 1:return "Priority"/协议break;case 0:return "Routine"/路由break;default:return "Unknow"break;char * parseServiceType_getTOS(BYTE b)b=(b>>1)&0x0f;/获取服务类型字段中的TOS子域switch(b) case 0:return "Normal service" /正常运行break;case 1:return "Minimize monetary cost" /成本break;case 2:return "Maximize reliability" /可靠性break;case 4:return "Maximize throughput" /吞吐量break;case 8:return "Minimize delay" /延迟break;case 15:return "Maximize security" /安全性break; default:return "Unknow" char * getProtocol(BYTE Protocol) /获取协议字段共8位switch(Protocol) /以下为协议号说明: case 1:return "ICMP" /Internet控制报文协议case 2:return "IGMP" /Internet组管理协议case 4:return "IP in IP"/移动IP数据封装和隧道case 6:return "TCP"/传输控制协议case 8:return "EGP"/外部网关协议case 17:return "UDP"/用户数据报文协议case 41:return "IPv6"case 46:return "RSVP"/资源预留协议case 89:return "OSPF"/Open Shortest Path First 开发式最短路径优先default:return "UNKNOW"void ipparse(FILE* file,IP_HEADER *ip_pointer)fseek(file,0,SEEK_END);fprintf(file,"版本号=%drn",ip_pointer->Version_HeadLen>>4);fprintf(file,"报头标长= %d (BYTE)rn",(ip_pointer->Version_HeadLen & 0x0f)*4); /首部长度是以4个字节为单位的fprintf(file,"服务器类型 = %s,%srn",parseServiceType_getProcedence(ip_pointer->ServiceType),parseServiceType_getTOS(ip_pointer->ServiceType);fprintf(file,"总长度 = %d(BYTE)rn",ip_pointer->TotalLen);fprintf(file,"标识 = %drn",ip_pointer->ID);fprintf(file,"标志位 DF=%d , MF=%drn",(ip_pointer->Flags_FragOff>>14)&0x01),(ip_pointer->Flags_FragOff>>13)&0x01);fprintf(file,"分段偏移值 = %drn",(ip_pointer->Flags_FragOff&0x1fff);fprintf(file,"生存期 = %d (hops)rn",ip_pointer->TimeToLive);fprintf(file,"协议 = %srn",getProtocol(ip_pointer->Protocol);fprintf(file,"头校验和 = 0x%0xrn",ip_pointer->HdrChksum);fprintf(file,"源IP地址 = %srn",inet_ntoa(*(in_addr*)&ip_pointer->SrcAddr);fprintf(file,"目的IP地址 = %srn",inet_ntoa(*(in_addr*)&ip_pointer->DstAddr);fprintf(file,"-rn");void assisgment(IP_HEADER *sou_pointer,IP_HEADER *des_pointer )des_pointer->Version_HeadLen=sou_pointer->Version_HeadLen;des_pointer->ServiceType=sou_pointer->ServiceType;des_pointer->TotalLen=sou_pointer->TotalLen;des_pointer->ID=sou_pointer->ID;des_pointer->TimeToLive=sou_pointer->TimeToLive;des_pointer->Protocol=sou_pointer->Protocol;des_pointer->SrcAddr=sou_pointer->SrcAddr;des_pointer->DstAddr=sou_pointer->DstAddr;void main()FILE* file;file=fopen("分片数据报头.txt","wb+");WORD rv;WSADATA WSAData; /定义了能够储存WSAStarup调用返回值的结构rv=MAKEWORD(2,2); /Winsock2版本WSAStartup(rv,&WSAData);SOCKET sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP); /创建套接字,sock为套接字描述符BOOL flag=true;setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(CHAR*)&flag,sizeof(flag);/任意类型、任意状态套接口的设置选项值char hostName128;gethostname(hostName,100); /获取主机名hostent * pHostIP;/获取本地IP地址pHostIP = gethostbyname(hostName);sockaddr_in addr_in;addr_in.sin_addr=*(in_addr *)pHostIP->h_addr_list0;addr_in.sin_family = AF_INET;addr_in.sin_port = htons(6000); /将无符号短整型主机数据转换为网络字节顺序数据bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in); DWORD dwBufferLen10; /设置网卡为混杂模式DWORD dwBufferInLen=1;DWORD dwBytesReturned=0;WSAIoctl(sock, IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);char bufferBUFFER_SIZE; /设置缓冲区int n=0; /n是一个标志用来使得输出更加调理char c;dosystem("cls"); IP_HEADER fragment_HeaderFRAGMENT_NUM; int size=recv(sock,buffer,BUFFER_SIZE,0); /接收数据包 IP_HEADER ip=*(IP_HEADER*)buffer; int fragment_num=(ip.TotalLen-(ip.Version_HeadLen & 0x0f)*4)/FRAGMENT_SIZE+1;printf("nn接受到IP数据报的报头信息是n");if (size>0) ipparse(file,&ip);ipparse(stdout,&ip); printf("nnIP数据报分片n");printf("-n");for(int j=0;j<fragment_num;j+)assisgment(&ip,&fragment_Headerj);/对总长度标志位和页偏移赋值unsigned short flags_flagoff;unsigned short total_len;WORD cs;if(j!=fragment_num-1)flags_flagoff=j*FRAGMENT_SIZE/8+(short)8192; /8192对应的是标志位的MFtotal_len=FRAGMENT_SIZE+(unsigned short)(ip.Version_HeadLen&0x0f)*4);elseflags_flagoff=j*FRAGMENT_SIZE/8;total_len=ip.TotalLen%FRAGMENT_SIZE +(unsigned short)(ip.Version_HeadLen&0x0f)*4);fragment_Headerj.Flags_FragOff=(WORD)flags_flagoff;fragment_Headerj.TotalLen=total_len;fragment_Headerj.HdrChksum=0;/checksum(fragment_Headerj,checksum);checksum(&fragment_Headerj,&cs);fragment_Headerj.HdrChksum=cs;ipparse(file,&fragment_Headerj);ipparse(stdout,&fragment_Headerj); fflush(stdin);cout<<"是否继续捕捉数据报?(Y/N)"<<endl;docin>>c;while(c!='n'&&c!='N'&&c!='y'&&c!='Y');elsecout<<"捕获数据失败"<<endl;while(c='y'|c='Y');fclose(file);closesocket(sock);-