logo资料库

C++实现IP数据包解析程序.doc

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
//#include "stdafx.h" #include "winsock2.h" #include "ws2tcpip.h" #include "iostream.h" #include "stdio.h" typedef struct _IP_HEADER { union { BYTE Version;//版本 BYTE HdrLen;//IHL }; BYTE ServiceType;//服务类型 WORD TotalLen;//总长 WORD ID;//标识 union { WORD Flags;//标志 WORD FragOff;//分段偏移 }; BYTE TimeToLive;//生命期 BYTE Protocol;//协议 WORD HdrChksum;//头校验和 DWORD SrcAddr;//源地址 DWORD DstAddr;//目的地址 BYTE Options;//选项 }IP_HEADER; //逐位解析 IP 头中的信息 void getVersion(BYTE b,BYTE &version) { version=b>>4; } void getIHL(BYTE b,BYTE &result) {
result=(b & 0x0f)*4; } 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 "Flash"; break; case 2: return "Immediate"; break; case 1: return "Priority"; break; case 0: return "Routine"; break; default: return "Unknown"; } } char *parseServiceType_getTOS(BYTE b)
{ b=(b>>1)&0x0f; 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 "Unknown"; } } void getFlags(WORD w,BYTE &DF,BYTE &MF) { DF=(w>>14)&0x01; MF=(w>>13)&0x01; } void getFragOff(WORD w,WORD &fragOff) { fragOff=w&0x1fff; }
char *getProtocol(BYTE Protocol) { switch(Protocol) { case 1: return "ICMP"; case 2: return "IGMP"; case 4: return "IP in IP"; case 6: return "TCP"; case 8: return "BGP"; case 17: return "UDP"; case 41: return "RSVP"; case 89: return "OSPF"; default: return "UNKNOWN"; } } void ipparse(FILE *file,char *buffer) { IP_HEADER ip=*(IP_HEADER *)buffer; fseek(file,0,SEEK_END); //解析版本信息 BYTE version; getVersion(ip.Version,version); fprintf(file,"版本=%d/r/n",version); //解析 IP 长度 BYTE headerLen; getIHL(ip.HdrLen,headerLen);
fprintf(file,"头长度=%d(BYTE)/r/n",headerLen); //解析服务类型 fprintf(file,"服务类型=%s,%s/r/n",parseServiceType_getProcedence(ip.ServiceType), parseServiceType_getTOS(ip.ServiceType)); //解析数据包长度 fprintf(file,"数据报长度=%d(BYTE)/r/n",ip.TotalLen); //解析数据包 ID fprintf(file,"数据报 ID=%d/r/n",ip.ID); //解析标志位 BYTE DF,MF; getFlags(ip.Flags,DF,MF); fprintf(file,"分段标志 DF=%d,MF=%d/r/n",DF,MF); //解析分段偏移 WORD fragOff; getFragOff(ip.FragOff,fragOff); fprintf(file,"分段偏移值=%d/r/n",fragOff); //解析生存期 fprintf(file,"生存期=%d/r/n",ip.TimeToLive); //解析协议 fprintf(file,"协议=%s/r/n",getProtocol(ip.Protocol)); //解析头校验和 fprintf(file,"头校验和=0x%0x/r/n",ip.HdrChksum); //解析 IP 地址 fprintf(file,"源 IP 地址=%s/r/n",inet_ntoa(*(in_addr *)&ip.DstAddr)); //解析目的 IP 地址 fprintf(file,"目的 IP 地址=%s/r/n",inet_ntoa(*(in_addr *)&ip.DstAddr)); fprintf(file,"--------------------------------------------------/r/n"); } int main(int argc,char *argv[]) { if(argc!=2) { printf("usage error!/n"); return -1;
} FILE *file; if((file=fopen(argv[1],"wb+"))==NULL) { printf("fail to open file %s",argv[1]); return -1; } WSADATA wsData; //初始化失败,程序退出 if(WSAStartup(MAKEWORD( 2, 2 ),&wsData)!=0) { printf("WSAStartup failed/n"); return -1; } SOCKET sock;//建立原始 socket if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET ) { printf("create socket failed!/n"); return -1; } BOOL flag=TRUE; //设置 IP 头操作选项,其中 flag 设置为 true,用户可以亲自对 IP 头进行处理 if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR) { printf("setsockopt failed!/n"); return -1; } char hostName[128]; if(gethostname(hostName,100)==SOCKET_ERROR) { printf("gethostname failed/n"); return -1; } //获取本地 IP 地址
hostent *pHostIP; if((pHostIP=gethostbyname(hostName))==NULL) { printf("gethostbyname failed/n"); return -1; } //地充 SOCKADDR_IN 结构 sockaddr_in addr_in; addr_in.sin_addr=*(in_addr *)pHostIP->h_addr_list[0]; addr_in.sin_family=AF_INET; addr_in.sin_port=htons(6000); //把原始 socket 绑定到本地网卡上 if(bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in))==SOCKET_ERROR) { printf("bind failed"); return -1; } DWORD dwValue=1; //设置 SOCK_RAW 为 SIO_RCVALL,以便接收所有的 IP 包 #define IO_RCVALL _WSAIOW(IOC_VENDOR,1) DWORD dwBufferLen[10]; DWORD dwBufferInLen=1; DWORD dwBytesReturned=0; if(WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,size of(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR) { printf("ioctlsocket failed/n"); cout<
printf("开始解析经过本机的 IP 数据包/n/n"); while(true) { int size=recv(sock,buffer,BUFFER_SIZE,0); if(size>0) { ipparse(stdout,buffer); ipparse(file,buffer); } } fclose(file); return 0; }
分享到:
收藏