路由跟踪器代码.docx
- 文档编号:18184506
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:9
- 大小:16.79KB
路由跟踪器代码.docx
《路由跟踪器代码.docx》由会员分享,可在线阅读,更多相关《路由跟踪器代码.docx(9页珍藏版)》请在冰点文库上搜索。
路由跟踪器代码
//路由跟踪器课程设计代码部分
//程序原理:
程序发送一个请求回显类型为8的icmp包,开始设置此包ttl为1,到达第一个路由器时,路由器会将ttl减1,此时ttl变为0,
//路由器即会丢弃此包,并发送一个超时类型为11的icmp包,程序接收此包,解析出此包的源ip,即为第一个路由器的ip,依次类推,
//发第二个请求回显icmp包,ttl设置为2,第二个路由器也会像上面第一个一样处理此包,即可获得第二个路由器的ip,这样不断的
//增加icmp包ttl值,当ttl足够大,icmp包可以到达目的地时,
//目的地会发送一个回应应答报文或者是目的地不可达报文,此时路由跟踪即完成
#include
#include
#include
usingnamespacestd;
#pragmacomment(lib,"Ws2_32.lib")
typedefstruct
{
unsignedcharhdr_len:
4;
unsignedcharversion:
4;
unsignedchartos;
unsignedshorttotal_len;
unsignedshortidentifier;
unsignedshortfrag_and_flags;
unsignedcharttl;
unsignedcharprotocol;
unsignedshortchecksum;
unsignedlongsourceIP;
unsignedlongdestIP;
}IP_HEADER;
typedefstruct
{
BYTEtype;//8位类型字段
BYTEcode;//8位代码字段
USHORTcksum;//16位校验和
USHORTid;//16位标识符
USHORTseq;//16位序列号
}ICMP_HEADER;
//报文解码结构
typedefstruct
{
USHORTusSeqNo;//序列号
DWORDdwRoundTripTime;//往返时间
in_addrdwIPaddr;//返回报文的IP地址
}DECODE_RESULT;
USHORTchecksum(USHORT*pBuf,intiSize)
{
unsignedlongcksum=0;
while(iSize>1)
{
cksum+=*pBuf++;
iSize-=sizeof(USHORT);
}
if(iSize)
{
cksum+=*(UCHAR*)pBuf;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}
BOOLDecodeIcmpResponse(char*pBuf,intiPacketSize,DECODE_RESULT&DecodeResult,BYTEICMP_ECHO_REPLY,BYTEICMP_TIMEOUT)
{
IP_HEADER*pIpHdr=(IP_HEADER*)pBuf;
intiIpHdrLen=pIpHdr->hdr_len*4;
if(iPacketSize<(int)(iIpHdrLen+sizeof(ICMP_HEADER)))
returnFALSE;
ICMP_HEADER*pIcmpHdr=(ICMP_HEADER*)(pBuf+iIpHdrLen);
USHORTusID,usSquNo;
if(pIcmpHdr->type==ICMP_ECHO_REPLY)//ICMP回显应答报文
{
usID=pIcmpHdr->id;//报文ID
usSquNo=pIcmpHdr->seq;//报文序列号
}
elseif(pIcmpHdr->type==ICMP_TIMEOUT)//ICMP超时差错报文
{
char*pInnerIpHdr=pBuf+iIpHdrLen+sizeof(ICMP_HEADER);//载荷中的IP头
intiInnerIPHdrLen=((IP_HEADER*)pInnerIpHdr)->hdr_len*4;//载荷中的IP头长
ICMP_HEADER*pInnerIcmpHdr=(ICMP_HEADER*)(pInnerIpHdr+iInnerIPHdrLen);//载荷中的ICMP头
usID=pInnerIcmpHdr->id;//报文ID
usSquNo=pInnerIcmpHdr->seq;//序列号
}
else
{
returnfalse;
}
if(usID!
=(USHORT)GetCurrentProcessId()||usSquNo!
=DecodeResult.usSeqNo)
{
returnfalse;
}
DecodeResult.dwIPaddr.s_addr=pIpHdr->sourceIP;
DecodeResult.dwRoundTripTime=GetTickCount()-DecodeResult.dwRoundTripTime;
if(pIcmpHdr->type==ICMP_ECHO_REPLY||pIcmpHdr->type==ICMP_TIMEOUT)
{
if(DecodeResult.dwRoundTripTime)
cout<<""< else cout<<""<<"<1ms"< } returntrue; } voidmain() { WSADATAwsa; WSAStartup(MAKEWORD(2,2),&wsa); charIpAddress[255]; cout<<"请输入一个IP地址或域名: "; cin>>IpAddress; //得到IP地址 u_longulDestIP=inet_addr(IpAddress); //转换不成功时按域名解析 if(ulDestIP==INADDR_NONE) { hostent*pHostent=gethostbyname(IpAddress); if(pHostent) { ulDestIP=(*(in_addr*)pHostent->h_addr).s_addr; } else { cout<<"输入的IP地址或域名无效! "< WSACleanup(); return; } } cout<<"Tracingrooteto"< sockaddr_indestSockAddr; ZeroMemory(&destSockAddr,sizeof(sockaddr_in)); destSockAddr.sin_family=AF_INET; destSockAddr.sin_addr.s_addr=ulDestIP; SOCKETsockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); //超时时间 intiTimeout=3000; //接收超时 setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeout,sizeof(iTimeout)); //发送超时 setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeout,sizeof(iTimeout)); //构造ICMP回显请求消息,并以TTL递增的顺序发送报文 //ICMP类型字段 constBYTEICMP_ECHO_REQUEST=8; constBYTEICMP_ECHO_REPLY=0; constBYTEICMP_TIMEOUT=11; //其他常量定义 constintDEF_ICMP_DATA_SIZE=32;//ICMP报文默认数据字段长度 constintMAX_ICMP_PACKET_SIZE=1024;//ICMP报文最大长度(包括报头) constDWORDDEF_ICMP_TIMEOUT=3000;//回显应答超时时间 constintDEF_MAX_HOP=30; charIcmpSendBuf[sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE];memset(IcmpSendBuf,0,sizeof(IcmpSendBuf));charIcmpRecvBuf[MAX_ICMP_PACKET_SIZE];memset(IcmpRecvBuf,0,sizeof(IcmpRecvBuf)); ICMP_HEADER*pIcmpHeader=(ICMP_HEADER*)IcmpSendBuf; pIcmpHeader->type=ICMP_ECHO_REQUEST;pIcmpHeader->code=0;pIcmpHeader->id=(USHORT)GetCurrentProcessId();memset(IcmpSendBuf+sizeof(ICMP_HEADER),'E',DEF_ICMP_DATA_SIZE);// USHORTusSeqNo=0; intiTTL=1; BOOLbReachDestHost=FALSE;//循环退出标志 intiMaxHot=DEF_MAX_HOP;//循环的最大次数 DECODE_RESULTDecodeResult;//传递给报文解码函数的结构化参数 while(! bReachDestHost&&iMaxHot--) { //设置IP报头的TTL字段 setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char*)&iTTL,sizeof(iTTL)); cout< //填充ICMP报文中每次发送变化的字段 ((ICMP_HEADER*)IcmpSendBuf)->cksum=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*)&destSockAddr,sizeof(destSockAddr)); //接收ICMP差错报文并进行解析处理 sockaddr_infrom;//对端socket地址 intiFromLen=sizeof(from);//地址结构大小 intiReadDataLen;//接收数据长度 while (1) { //接收数据 iReadDataLen=recvfrom(sockRaw,IcmpRecvBuf,MAX_ICMP_PACKET_SIZE,0,(sockaddr*)&from,&iFromLen); 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地址 cout<<"\t"< break; } } elseif(WSAGetLastError()==WSAETIMEDOUT) { cout<<"*"<<"\t"<<"Requesttimedout."< break; } else { break; } } iTTL++;} }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 路由 跟踪 代码