资源预览内容
第1页 / 共12页
第2页 / 共12页
第3页 / 共12页
第4页 / 共12页
第5页 / 共12页
第6页 / 共12页
第7页 / 共12页
第8页 / 共12页
第9页 / 共12页
第10页 / 共12页
亲,该文档总共12页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
/路由跟踪器课程设计代码部分/程序原理:程序发送一个请求回显类型为 8 的 icmp 包,开始设置此包 ttl 为 1,到达第一个路由器时,路由器会将 ttl 减 1,此时 ttl 变为 0,/ 路由器即会丢弃此包,并发送一个超时类型为 11 的icmp 包,程序接收此包,解析出此包的源 ip,即为第一个路由器的ip,依次类推,/ 发第二个请求回显 icmp 包,ttl 设置为 2,第二个路由器也会像上面第一个一样处理此包,即可获得第二个路由器的 ip, 这样不断的/ 增加 icmp 包 ttl 值,当 ttl 足够大, icmp 包可以到达目的地时,/ 目的地会发送一个回应应答报文或者是目的地不可达报文,此时路由跟踪即完成#include #include #include using namespace std;#pragma comment(lib, Ws2_32.lib)typedef structunsigned char hdr_len:4; unsigned char version:4; unsigned char tos; unsigned short total_len; unsigned short identifier; unsigned short frag_and_flags; unsigned char ttl; unsigned char protocol; unsigned short checksum; unsigned long sourceIP; unsigned long destIP; IP_HEADER;typedef structBYTE type; /8 位类型字段BYTE code; /8 位代码字段USHORT cksum; /16 位校验和USHORT id; /16 位标识符USHORT seq; /16 位序列号 ICMP_HEADER;/报文解码结构typedef structUSHORT usSeqNo; /序列号DWORD dwRoundTripTime; /往返时间in_addr dwIPaddr; /返回报文的 IP 地址DECODE_RESULT;USHORT checksum(USHORT *pBuf,int iSize)unsigned long cksum=0;while(iSize1)cksum+=*pBuf+;iSize-=sizeof(USHORT);if(iSize)cksum+=*(UCHAR *)pBuf;cksum=(cksum16)+(cksumreturn (USHORT)(cksum);BOOL DecodeIcmpResponse(char * pBuf,int iPacketSize,DECODE_RESULT &DecodeResult,BYTE ICMP_ECHO_REPLY,BYTE ICMP_TIMEOUT)IP_HEADER* pIpHdr = (IP_HEADER*)pBuf;int iIpHdrLen = pIpHdr-hdr_len * 4;if (iPacketSize type=ICMP_ECHO_REPLY) /ICMP 回显应答报文usID=pIcmpHdr-id; /报文 IDusSquNo=pIcmpHdr-seq; /报文序列号else if(pIcmpHdr-type=ICMP_TIMEOUT) /ICMP 超时差错报文char * pInnerIpHdr=pBuf+iIpHdrLen+sizeof(ICMP_HEADER); /载荷中的 IP 头int iInnerIPHdrLen=(IP_HEADER *)pInnerIpHdr)-hdr_len*4; /载荷中的 IP 头长ICMP_HEADER * pInnerIcmpHdr=(ICMP_HEADER *)(pInnerIpHdr+iInnerIPHdrLen);/载荷中的 ICMP 头usID=pInnerIcmpHdr-id; /报文 IDusSquNo=pInnerIcmpHdr-seq; /序列号elsereturn false;if(usID!=(USHORT)GetCurrentProcessId()|usSquNo!=DecodeResult.usSeqNo)return false;DecodeResult.dwIPaddr.s_addr=pIpHdr-sourceIP;DecodeResult.dwRoundTripTime=GetTickCount()-DecodeResult.dwRoundTripTime;if (pIcmpHdr-type = ICMP_ECHO_REPLY |pIcmpHdr-type = ICMP_TIMEOUT)if(DecodeResult.dwRoundTripTime)coutIpAddress;/得到 IP 地址u_long ulDestIP=inet_addr(IpAddress);/转换不成功时按域名解析if(ulDestIP=INADDR_NONE)hostent * pHostent=gethostbyname(IpAddress);if(pHostent)ulDestIP=(*(in_addr*)pHostent-h_addr).s_addr;elsecouttype=ICMP_ECHO_REQUEST; pIcmpHeader-code=0; pIcmpHeader-id=(USHORT)GetCurrentProcessId();memset(IcmpSendBuf+sizeof(ICMP_HEADER),E,DEF_ICMP_DATA_SIZE);/ USHORT usSeqNo=0;int iTTL=1; BOOL bReachDestHost=FALSE; /循环退出标志int iMaxHot=DEF_MAX_HOP; /循环的最大次数DECODE_RESULT DecodeResult; /传递给报文解码函数的结构化参数while(!bReachDestHost&iMaxHot-)/设置 IP 报头的 TTL 字段setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char *)coutcksum=0; /校验和先置为 0(ICMP_HEADER *)IcmpSendBuf)-seq=htons(usSeqNo+); /填充序列号(ICMP_HEADER *)IcmpSendBuf)-cksum=checksum(USHORT *)IcmpSendBuf,sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE); /计算校验和/记录序列号和当前时间DecodeResult.usSeqNo=(ICMP_HEADER*)IcmpSendBuf)-seq; /当前序号DecodeResult.dwRoundTripTime=GetTickCount(); /当前时间/发送 TCP 回显请求信息sendto(sockRaw,IcmpSendBuf,sizeof(IcmpSendBuf),0,(sockaddr*)/接收 ICMP 差错报文并进行解析处理sockaddr_in from; /对端 socket 地址int iFromLen=sizeof(from); /地址结构大小int iReadDataLen; /接收数据长度while(1)/接收数据iReadDataLen=recvfrom(sockRaw,IcmpRecvBuf,MAX_ICMP_PACKET_SIZE,0,(sockaddr*)if(iReadDataLen!=SOCKET_ERROR) /有数据到达if(DecodeIcmpResponse(IcmpRecvBuf,iReadDataLen,DecodeResult,ICMP_ECHO_REPLY,ICMP_TIMEOUT)if(DecodeResult.dwIPaddr.s_addr=destSockAddr.sin_addr.s_addr)bReachDestHost=true;/输出 IP 地址couttinet_ntoa(DecodeResult.dwIPaddr)endl;break;else if(WSAGetLastError()=WSAETIMEDOUT)cout *tRequest timed out.endl;break;elsebreak;iTTL+;
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号