您好,欢迎访问三七文档
集美大学计算机工程学院实验报告课程名称:TCP/IP协议与通信程序设计班级:实验成绩:实验项目名称:路由跟踪程序仿真学号:上机实践日期:2016-06-16实验项目编号:13组号:1上机实践时间:2学时一、实验目的了解利用原始套接字进行通信程序的编写,编译和执行二、实验内容与设计思想基于原始套接字编写路由跟踪仿真程序,以跟踪获取本机的IP数据包到达集美大学教务处网站服务主机(210.34.129.66)所经历的路由器的IP地址,并在客户端显示出来。提示:本机程序向目标主机发送一个封装ICMP回显请求的数据报,初始化TTL为1,当该包到达途中第一个路由器时,TTL值减为0发生超时错误,第一个路由器反馈源主机ICMP超时差错报文。依次将数据报的TTL值递增1,以便IP包能到达下一个路由器,如法炮制,直到数据报达到目地主机,目地主机将返回ICMP回显应答消息。源主机依次解析处理期间收到的ICMP报文就可以得出数据报从源主机到达目地主机途中所经过的路由器IP。三、实验使用环境操作系统:MicrosoftWindowsXPSP2编程环境:VisualC++6.0四、实验步骤和调试过程源代码:#defineWIN32_LEAN_AND_MEAN#includewinsock2.h//使用原始套接字需要WinSock2的支持#includews2tcpip.h//进行IPPROTO_IP级别设置时用到#includestdio.h#includestdlib.h#defineICMP_ECHO8//发送Ping请求时的ICMP报文类型#defineICMP_ECHOREPLY0//接收Ping回复时的ICMP报文类型#defineICMP_TIMEOUT11//ICMP超时报文类型#defineICMP_MIN8//Minimum8-byteICMPpacket(header)#defineMAX_PACKET1024//MaxICMPpacketsize#defineDEICMP_PACKSIZE44//DefautICMPPACKETSIZEcharlpdest[16];//用来存放目的IP地址DWORDcStartTickCount;//用来存放发送包的起始时间#pragmacomment(lib,ws2_32.lib)typedefstruct_icmphdr//ICMP头部定义,被封装在IP包中{BYTEi_type;//报文类型BYTEi_code;//代码USHORTi_cksum;//校验和USHORTi_id;//标识符USHORTi_seq;//序号}IcmpHeader;//初始化ICMP头部voidFillICMPData(char*icmp_data,intdatasize){IcmpHeader*icmp_hdr=NULL;char*datapart=NULL;icmp_hdr=(IcmpHeader*)icmp_data;icmp_hdr-i_type=ICMP_ECHO;//requestanICMPechoicmp_hdr-i_code=0;icmp_hdr-i_id=(USHORT)GetCurrentProcessId();icmp_hdr-i_cksum=0;icmp_hdr-i_seq=0;datapart=icmp_data+sizeof(IcmpHeader);memset(datapart,'E',datasize-sizeof(IcmpHeader));}//校验和函数USHORTchecksum(USHORT*buffer,intsize){unsignedlongcksum=0;while(size1){cksum+=*buffer++;size-=sizeof(USHORT);}if(size)cksum+=*(UCHAR*)buffer;cksum=(cksum16)+(cksum&0xffff);cksum+=(cksum16);return(USHORT)(~cksum);;}intDecodeIPHeader(char*buf,intbytes,structsockaddr_in*from){IcmpHeader*icmphdr=NULL;DWORDtick;staticinticmpcount=1;unsignedshortiphdrlen;//判断接收操作是否超时if(!buf){printf(%2d:***.***.***.***Requesttimedout.\n,icmpcount++);return1;}tick=GetTickCount();iphdrlen=(buf[0]&0x0f)*4;icmphdr=(IcmpHeader*)(buf+iphdrlen);if(bytesiphdrlen+ICMP_MIN){printf(Toofewbytesfrom%s\n,inet_ntoa(from-sin_addr));return0;}//判断接收的ICMP报文是否为超时报文if(icmphdr-i_type==ICMP_TIMEOUT&&icmphdr-i_code==0){printf(%2d:%-15s%4dms\n,icmpcount++,inet_ntoa(from-sin_addr),tick-cStartTickCount);return0;}//判断接收的ICMP报文是否为回复报文elseif(icmphdr-i_type==ICMP_ECHOREPLY&&icmphdr-i_id==GetCurrentProcessId()){printf(%2d:%-15s%4dms\n,icmpcount++,inet_ntoa(from-sin_addr),tick-cStartTickCount);printf(Tracecomplete!\n);return1;}//其他类型,表示不可达else{printf(%2d:Destinationhostisunreachable!\n,icmpcount++);return1;}}intmain(){WSADATAwsaData;SOCKETsockRaw=INVALID_SOCKET;structsockaddr_indest,from;inti,bread,fromlen=sizeof(from),timeout=1000,ret;structhostent*hp=NULL;char*icmp_data=NULL,*recvbuf=NULL;USHORTseq_no=0;printf(输入追踪的目的(IP/主机名):);scanf(%s,lpdest);if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){printf(WSAStartup()failed:%d\n,GetLastError());return-1;}//创建套接字sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);if(sockRaw==INVALID_SOCKET){printf(WSASocket()failed:%d\n,WSAGetLastError());return-1;}//对锁定套接字设置超时bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));if(bread==SOCKET_ERROR){printf(setsockopt(SO_RCVTIMEO)failed:%d\n,WSAGetLastError());return-1;}timeout=1000;bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));if(bread==SOCKET_ERROR){printf(setsockopt(SO_SNDTIMEO)failed:%d\n,WSAGetLastError());return-1;}//解析目标地址,将主机名转化为IP地址memset(&dest,0,sizeof(dest));dest.sin_family=AF_INET;if((dest.sin_addr.S_un.S_addr=inet_addr(lpdest))==INADDR_NONE){if((hp=gethostbyname(lpdest))!=NULL){memcpy(&(dest.sin_addr.S_un.S_addr),hp-h_addr_list[0],hp-h_length);dest.sin_family=hp-h_addrtype;printf(dest.sin_addr=%s\n,inet_ntoa(dest.sin_addr));}else{printf(gethostbyname()failed:%d\n,WSAGetLastError());return-1;}}//CreatetheICMPpakceticmp_data=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);recvbuf=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);if(!icmp_data){printf(HeapAlloc()failed:%d\n,GetLastError());return-1;}memset(icmp_data,0,MAX_PACKET);FillICMPData(icmp_data,DEICMP_PACKSIZE);printf(跳IP地址耗时\n);//开始发送/接收ICMP报文for(i=1;i=255;i++){intbwrote;//设置IP包的生存期ret=setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char*)&i,sizeof(int));if(ret==SOCKET_ERROR){printf(setsockopt(IP_TTL)failed:%d\n,WSAGetLastError());}((IcmpHeader*)icmp_data)-i_cksum=0;((IcmpHeader*)icmp_data)-i_seq=seq_no++;//SequencenumberofICMPpackets((IcmpHeader*)icmp_data)-i_cksum=checksum((USHORT*)icmp_data,DEICMP_PACKSIZE);//发送ICMP包请求查询cStartTickCount=GetTickCount();bwrote=sendto(sockRaw,icmp_data,DEICMP_PACKSIZE,0,(structsockaddr*)&dest,sizeof(dest));if(bwrote==SOCKET_ERROR){if(WSAGetLastError()==WSAETIMEDOUT){printf(timedout\n);continue;}printf(sendto()failed:%d\n,WSAGetLastError());return-1;}if(bwroteDEICMP_PACKSIZE){printf(Wrote%dbytes\n,bwrote);}//接收ICMP回复包bread=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(structsockaddr*)&from,&fromlen);if(bread==
本文标题:路由跟踪程序仿真
链接地址:https://www.777doc.com/doc-7304059 .html