traceroute程序设计与实现.docx
- 文档编号:12148791
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:20
- 大小:85.75KB
traceroute程序设计与实现.docx
《traceroute程序设计与实现.docx》由会员分享,可在线阅读,更多相关《traceroute程序设计与实现.docx(20页珍藏版)》请在冰豆网上搜索。
traceroute程序设计与实现
Traceroute程序设计与实现
学生姓名:
樊冠宇指导老师:
姜文超
摘要本文主要讲述了路由追踪的基本程序设计与实现,并给出了一种基于IP网络的路由追踪命令Tracert,详细分析了实现路由追踪的基本原理,归纳了路由追踪的基本流程。
Tracert通过ICMP协议和IPheader中TTL(存活时间)利用路由器对数据报存活时间的处理方式来实现路由探测的。
首先根据任务书设计好流程图,然后编写程序代码,运行得到Traceroute的命令窗口。
提取tracert的输出,再结合现有IP数据库及自建地名-坐标数据库对路由中各节点IP进行定位,最终实现了动态显示追踪的详细信息和路径。
关键词:
IP地址,ICMP协议,TTL,Tracert路由追踪
1引言
Internet,是目前世界上最大的计算机网络,更确切的说是网络中的网络,它由遍布全球的几万局域网和数百万台计算机组成,并通过用于异构网络的TCP/IP协议进行网间通信。
互联网中,信息的传送是通过网中许多段的传输介质和设备从一端到达另一端。
每一个连接在Internet上的设备,如主机、路由器、接入服务器等一般情况下都会有一个独立的IP地址。
通过Traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路劲。
当然每次数据包由某一同样的出发点到达某一同样的目的地走的路劲可能会不同,但基本上来说大部分时候所走的路由是相同的。
随着Internet(国际互联网)的发展,越来越多的服务通过网络提供给大众,与此同时,针对互联网的攻击事件也越来越频繁。
所谓路由追踪实际上就是在IP网络上判断从源到达目的所经过的路由器的IP地址,其基本的实现手段都是向目的地发送数据包以获取经过的路由器的IP。
由于Internet上的路由协议是动态的,所以每次形成的数据包从同一个出发点到达目的地的路由可能会不一样,但由于路由算法有一定的稳定性,在大部分时侯所走的路由会是相同的。
课程设计目的
1.这次课程设计,主要为了加深同学们对计算机网络网络的理解和认识
2.了解信息在计算机网络与网络之间的传送和接收
3.进一步加深了解网络与网络之间的协议
4.理解网络中的IP地址以及路由之间的相关命令。
课程设计内容
1.已知参数:
输入:
目的节点IP地址或主机名;输出:
从控制台屏幕输出IP报文由本机出发到达目的主机所经过的路由信息。
2.设计要求:
通过原始套接字编程,实现Tracert的基本功能
初始化WindowsSockets网络环境;
解析命令行参数,构造目的端socket地址;
定义IP、ICMP报文;
接收ICMP差错报文并进行解析。
课程设计要求
(1)按要求编写课程设计报告书,能正确阐述设计结果。
(2)通过课程设计培养学生严谨的科学态度,认真的工作作风和团队协作精神。
(3)学会文献检索的基本方法和综合运用文献的能力。
(4)在老师的指导下,要求每个学生独立完成课程设计的全部内容。
2设计原理
raceroute是一个路由跟踪命令,它通过ICMP协议和IPheader中TTL(存活时间)来实现的。
具体而言就是:
发送方发出一个TTL是1的IPDatagram(事实上每个数据包发送三次,大小为40字节,包括本机的IP地址,目的主机的IP地址以及时间戳),当经由第一个路由器时,路由器将该数据包的TTL减1,发现此时的TTL为0,将数据包丢失,同时向源主机发送一个ICMPTime-to-Exceed报文(包括源主机的IP地址、路由地址以及路由的相关消息),源主机收到这个数据包后就知道了这个路由器在这条路径上。
同理发送第二个、第三个......第n个。
源主机将每次IP数据报的TTL+1,直到某个数据报到达了目的地址,此时不知发回一个ICMP Time-to-Exceed,而是发送一个数据报的响应报文。
当源主机收到这样一个报文后便知道数据包已经到达了目的地。
Traceroute提取发ICMPTTL到期消息设备的IP地址并作域名解析。
每次,Traceroute都打印出一系列数据,包括所经过的路由设备的域名及IP地址,三个包每次来回所花时间。
Traceroute有一个固定的时间等待响应(ICMPTTL到期消息)。
如果这个时间过了,它将打印出一系列的*号表明:
在这个路径上,这个设备不能在给定的时间内发出ICMPTTL到期消息的响应。
然后,Traceroute给TTL记数器加1,继续进行。
简介和基本原理
ICMP(InternetControlMessageProtocol),即Internet控制报文协议, 它是TCP/IP协议族的一个子协议,属于网络层面向无连接的协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。
当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。
ICMP报文被包装成IP数据包传到数据链路层进行传输。
通过ICMP协议,主机和路由器可以报告错误并交换相关的状态信息。
ICMP对于TCP/IP协议的可靠运行是至关重要的。
ICMP报文结构如图1所示:
程序的基本原理
路由追踪的主要原理是根据路径上各路由器对数据报的存活时(TimetoLive,TTL)做不同的处理,使其产生超时ICMP消息响应,反馈至源主机,从而获得此跳路由器或主机的IP。
照此再发送下一个TTL经过自增的数据报,直至获得整个路由中各节点的IP或者接收到错误的消息。
详细过程描述如下:
1)置n=1。
假设该过程中共经过M个路由器。
2)源主机S向目标主机D发送一个TTL为n的UDP数据报。
并设定端口号(一般大于30000)。
3)路由器(或者网关、主机)Rn对接收到的数据报的TTL值n做减1处理。
4)若n=0,则丢弃UDP数据报,向源主机S发送ICMP超时报文。
5)若n≥1,继续向目标主机D发送经过处理的数据报。
6)源主机S分析返回的ICMP报文,从中提取出发送者Rn的地址IPn并做记录。
7)若收到“端口不可达”的ICMP报文,则发送方即目标主机D,记录其地址IPn,追踪完成。
8)置n=n+1,继续向目标主机D发送TTL为n的数据报。
注意,这里使UDP数据报的端口号大于30000,是因为一般的应用程序不可能使用如此高的端口号。
当然这并非绝对,若出现例外,则源主机会发现等待超时,于是随机改变此UDP数据报的端口号,再次发送。
这样最终可以在目标主机上找到一个空闲的端口号。
另外,这里假设路由器和目标主机没有被配置为“过滤ICMP”或者做了其他的非常规处理,如果被做了类似的配置,则上面的追踪机制就无能为力了。
实现的功能
IP数据报的首部由两部分构成:
固定部分和可变部分。
固定部分的长度是20个字段,可变部分由许多选项构成,最长可达40个字节。
虽然选项并不是IP数据报的必需部分,但选项的处理却是IP软件的必需部分。
在现在的TCP/IP协议中,只定义了六种选项,对于我们进行路由追踪技术有用的是记录路由选项,一个记录路由选项是用来记录处理IP数据报的互联网路由器的IP地址。
因为首部的最大长度是60个字节,它包括20个字节的基本首部。
这就意味着只剩下40个字节留下给选项部分,所以通过选项字段最多能够记录9个路由器的IP地址。
源站在选项中创建一个位标置(placeholder),用来填入所经过的各路由器,图2给出了记录路由选项的格式。
图2记录路由选项
向目的主机发送一个ICMP报文,这种方法只要求使用一个套接字。
ICMP即Internet控制报文协议,是一种用于特殊用途的报文机制,可以使互联网中的路由器或主机报告差错或提供有关意外情况的信息。
尽管UDP和ICMP工作在TCP/IP的不同层次上,但他们的封装是类似的。
ICMP报文为两级封装ICMP报文放在IP数据报的数据部分,数据报则放在帧的数据中进行网络传输(如图3所示)ICMP报文与其他普通报文一样,具有相同的路由选择,并没有特殊的优先权和增加可靠性。
通过路由选项的方法记录路由的实现同UDP数据报是相似的,这里主要说明通过TTL方法的实现。
图3ICMP报文的两级封装
3设计步骤
分析本次课程设计的任务书,整个课程设计的过程大致可以分为三个步骤:
第一步主要是设计好流程图;第二步是根据流程图编写程序代码;第三步是在程序编译通过后,运行程序结果,在对话框中输入要追踪的IP地址,观察路由追踪命令追踪IP地址在网络中的运行。
其中第一步跟第二步是关键,只有完整的流程图和根据要求编写好正确的程序,才能运行得到正确的结果。
下面是整个设计过程中各个步骤的详细分析。
流程图
根据要求设计好的流程图如图4所示:
图4流程图
的核心程序
整个设计过程的核心程序代码:
#include""
#include""
#include""
#include""
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
voidCPing:
:
Ping(inttimeout)
{m_hSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);
if(m_hSocket==INVALID_SOCKET)
{AfxMessageBox("socket创建失败!
");
return;}
Startsending/receivingICMPpackets开始发送/接收ICMP的数据包
TCP/IPIllustrated,Volum1:
TheProtocols[M]1北京:
机械工业出版社,.
[2]WRichardStevens.UNIXNetworkProgrammingVolum1NetworkingAPIs:
SocketsandXTI(Second
Edition)(影印版)[M].北京:
清华大学出版社,2002.
[3][日]井口信和.TCP/IP网络工具篇[M].吴松芝,董江洪译.北京:
科学出版社,2003.1582162.
[4]余青霓,王晓程,周钢,等.网络入侵检测分析员手册[Z].北京:
人民邮电出版社,2000.1012109.
[5]JAMES,KEITHComputerNetworkingATop2DownApproachFeaturingtheInternet(影印版)[M].北京:
高等教育出版社,2001.
[6]李为民,赵迎新,梁济仁,等.网络连通性测试与故障定位[J].计算机应用,2004,24(增刊):
47249.
[7]张保通.基于路由器的防火墙设计[J].华北航天工业学院学报,2002,
(2):
16219.
附加程序清单:
莫小锋通信0802班学号:
0224
源程序:
#include""
#include""
#include""
#include""
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
//IP
structIPHEADER
{unsignedinth_len:
4;//首部长度
unsignedintversion:
4;//版本
unsignedchartos;//服务类型
unsignedshorttotal_len;//报文总长度
unsignedshortident;//标识
unsignedshortfrag_and_flags;//偏移量
unsignedcharttl;//寿命
unsignedcharproto;//协议
unsignedshortchecksum;//首部校验和
unsignedintsourceIP;//源站IP
unsignedintdestIP;//目的站IP
};
//ICMP首部数据结构
structICMPHEADER
{
BYTEi_type;//类型
BYTEi_code;//代码
USHORTi_cksum;//首部校验和
USHORTi_id;//标识
USHORTi_seq;//序列号
ULONGtimestamp;//时间戳(选用)
};
CTracer:
:
CTracer()
{
m_nSeq=1;
icmpData=NULL;
icmpRcvBuf=NULL;
m_hSocket=INVALID_SOCKET;
//初始化socket
WSADATAwsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!
=0)
{
AfxMessageBox("WSAStartup()出错!
");
}
}
CTracer:
:
~CTracer()
{
//关闭Socket
if(m_hSocket!
=NULL)
closesocket(m_hSocket);
WSACleanup();
}
//CheckSum
USHORTCTracer:
:
CheckSum(char*pBuffer,intsize)
{
USHORT*buffer=(USHORT*)pBuffer;
unsignedlongcksum=0;
while(size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
cksum+=*(UCHAR*)buffer;
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}
//FillAddress
BOOLCTracer:
:
FillAddress(char*addrDest)
{
memset(&m_addrDest,0,sizeof(m_addrDest));
=AF_INET;
if(inet_addr(addrDest)==INADDR_NONE)
{
//输入的地址为计算机名字
HOSTENT*hp=NULL;
hp=gethostbyname(addrDest);
if(hp)
{
memcpy(&,hp->h_addr,hp->h_length);
=hp->h_addrtype;
}
else
{
AfxMessageBox("获取地址失败!
");
returnFALSE;
}
}
else
{
}
returnTRUE;
}
//FillICMPData
voidCTracer:
:
FillICMPData(char*icmpData,intsize)
{
memset(icmpData,0,size);
ICMPHEADER*icmpHeader=NULL;
icmpHeader=(ICMPHEADER*)icmpData;
icmpHeader->i_type=ICMP_ECHO;
icmpHeader->i_code=0;
icmpHeader->i_id=(USHORT)GetCurrentProcessId();
icmpHeader->i_seq=m_nSeq++;
//GetTickCount返回从0点到现在的毫秒数,作时间戳
icmpHeader->timestamp=GetTickCount();
char*datapart=icmpData+sizeof(ICMPHEADER);
memset(datapart,'*',size-sizeof(ICMPHEADER));
//填充校验和
icmpHeader->i_cksum=CheckSum(icmpData,size);
}
//设置数据报的寿命
BOOLCTracer:
:
SetTTL(SOCKEThSocket,intttl)
{
intresult;
result=setsockopt(hSocket,IPPROTO_IP,IP_TTL,(LPSTR)&ttl,sizeof(ttl));
if(result==SOCKET_ERROR)
{
AfxMessageBox("设置数据报寿命失败!
");
TerminateProcess(GetCurrentProcess(),-1);
}
returnTRUE;
}
//发送数据报
BOOLCTracer:
:
SendData(char*icmpData,intsize)
{
//填充ICMP报头
FillICMPData(icmpData,size);
//发送数据报
intresult;
time1=GetTickCount();
result=sendto(m_hSocket,icmpData,size,0,(SOCKADDR*)&m_addrDest,sizeof(m_addrDest));
if(result==SOCKET_ERROR)
{
if(WSAGetLastError()==WSAETIMEDOUT)
{
((CTraceRouteDlg*)m_pWnd)->InfoAdd("发送超时");
returnTRUE;
}
AfxMessageBox("发送报文失败!
");
TerminateProcess(GetCurrentProcess(),-1);
}
returnFALSE;
}
//接收数据报
BOOLCTracer:
:
RecvData(char*icmpRcvBuf,int*presult)
{
staticintcount=0;
//总共6次出现接收超时,判断存在连接问题。
if(count>5)
{
AfxMessageBox("连接存在问题!
");
TerminateProcess(GetCurrentProcess(),-1);
}
intfromlen=sizeof(SOCKADDR);
*presult=SOCKET_ERROR;
*presult=recvfrom(m_hSocket,icmpRcvBuf,MAX_PACKET,0,(SOCKADDR*)&m_addrFrom,&fromlen);
time2=GetTickCount();
if(*presult==SOCKET_ERROR)
{
if(WSAGetLastError()==WSAETIMEDOUT)
{
((CTraceRouteDlg*)m_pWnd)->InfoAdd("接收超时!
");
count++;
returnTRUE;
}
AfxMessageBox("接收数据报失败!
");
TerminateProcess(GetCurrentProcess(),-1);
}
returnFALSE;
}
//处理接收到的数据报
BOOLCTracer:
:
DecodeICMP(char*pBuffer,intbytes,intttl)
{
IPHEADER*ipHeader=NULL;
ICMPHEADER*icmpHeader=NULL;
unsignedshortipHeaderLen;
HOSTENT*ph=NULL;
in_addrinaddr=;
ipHeader=(IPHEADER*)pBuffer;
ipHeaderLen=20;
if(bytes AfxMessageBox("接收数据报长度不正确! "); icmpHeader=(ICMPHEADER*)(pBuffer+20); switch(icmpHeader->i_type) { //目的站点的返回 caseICMP_ECHOREPLY: ph=gethostbyaddr((constchar*)&inaddr,AF_INET,sizeof(in_addr)); if(ph! =NULL) { CStringreport; ("%2d%s(%s)",ttl,ph->h_name,inet_ntoa(inaddr)); ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report); } returnTRUE; break; //中途路由器的返回 caseICMP_TIMEOUT: { CStringreport; ("%2d%s%2dms",ttl,inet_ntoa(inaddr),(time2-time1)); ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report); returnFALSE; break; } //错误: 主机不可达 caseICMP_DESTUNREACH: { CStringreport; ("%2d%s主机不可达",ttl,inet_ntoa(inaddr)); ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report); returnTRUE; break; } //收到一个不是回应的报文 default: { CStringreport; ("非回应报文"); ((CTraceRouteDlg*)m_pWnd)->InfoAdd(report); returnTRUE; } } returnFALSE; } voidCTracer: : SetWnd(CDialog*pWnd) { //设置窗口指针 m_pWnd=pWnd;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- traceroute 程序设计 实现