[关键字] ICMP 路由跟踪 Visual C++6.0
一、概述
计算机在Internet中传递信息时,必须要经过路由器进行网络路由才能找到目的主机,把信息送到目的主机。路由器中都有一张路由表,表中保存了从本路由器到某一主机的路由信息,路由器就是通过该路由表进行网络寻径的。两台主机之间并没有一条固定的路径(即路由表并不固定),该路径随着网络的变动而作相应的变动,因而我们并不能直接从某一主机上得到去往另一主机的路径,要得到本机与网络上某台主机的网络路径就必须要进行路由跟踪。本文将介绍一种实现路由跟踪的方法。
二、ICMP简介
ICMP即Internet控制报文协议是一种用于特殊用途的报文机制,可以使互联网中的路由器或主机报告差错或提供有关意外情况的信息。
ICMP报文为两级封装,ICMP报文放在IP数据报的数据部分,IP数据报则放在帧的数据中进行网络传输(如下图1所示)。ICMP报文与其他普通报文一样,具有相同的路由选择,并没有特殊的优先权和增加可靠性。

(图1)ICMP报文的封装
在ICMP包头中包含了三个字段:1字节类型域、1字节代码域、2字节校验和。类型域表示了该报文的类型,如:回应请求报文,数据报超时报文等,代码域表示了该类型的几种不同情况,如:当类型为11(超时报文)时,代码为0表示TTL超时,为1表示片重组超时。在实现本文中所述的功能时要发送回应请求报文(类型为8),过程如下:源主机向目的主机发送一个类型为8的回应请求报文,若目的站点收到回应请求报文则把报文IP包头部中的目的IP与源IP地址交换,将类型8改为回应类型0,计算出新的校验和再发往源主机。若源主机收到了该回应报文,则不但说明了目的主机可达,而且说明目的主机与源主机之间的路由器工作正常,源主机和目的主机的IP、ICMP软件运行正常。但若在传输过程中了出现了某些问题,如网络不通等,导致数据被定向到一个无效的目的地,这时相关路由器或目的主机将发回目的不可达报文(类型为3),并在代码中说明该报文的具体情况:是网络不可达还是主机不可达等。若请求报文在传输过程中超时,即TTL被减为0(报文每经过一个路由器TTL都要减1),则该路由器返回一个TTL超时报文(类型为11),报文IP头中源IP地址即为本路由器的IP地址。
[摘要] 本文简单介绍了ICMP协议和一种利用ICMP在VC++下实现网络路由跟踪的方法,并给出一了个详细的例子。
[关键字] ICMP 路由跟踪 Visual C++6.0
一、概述
计算机在Internet中传递信息时,必须要经过路由器进行网络路由才能找到目的主机,把信息送到目的主机。路由器中都有一张路由表,表中保存了从本路由器到某一主机的路由信息,路由器就是通过该路由表进行网络寻径的。两台主机之间并没有一条固定的路径(即路由表并不固定),该路径随着网络的变动而作相应的变动,因而我们并不能直接从某一主机上得到去往另一主机的路径,要得到本机与网络上某台主机的网络路径就必须要进行路由跟踪。本文将介绍一种实现路由跟踪的方法。
二、ICMP简介
ICMP即Internet控制报文协议是一种用于特殊用途的报文机制,可以使互联网中的路由器或主机报告差错或提供有关意外情况的信息。
ICMP报文为两级封装,ICMP报文放在IP数据报的数据部分,IP数据报则放在帧的数据中进行网络传输(如下图1所示)。ICMP报文与其他普通报文一样,具有相同的路由选择,并没有特殊的优先权和增加可靠性。

(图1)ICMP报文的封装
在ICMP包头中包含了三个字段:1字节类型域、1字节代码域、2字节校验和。类型域表示了该报文的类型,如:回应请求报文,数据报超时报文等,代码域表示了该类型的几种不同情况,如:当类型为11(超时报文)时,代码为0表示TTL超时,为1表示片重组超时。在实现本文中所述的功能时要发送回应请求报文(类型为8),过程如下:源主机向目的主机发送一个类型为8的回应请求报文,若目的站点收到回应请求报文则把报文IP包头部中的目的IP与源IP地址交换,将类型8改为回应类型0,计算出新的校验和再发往源主机。若源主机收到了该回应报文,则不但说明了目的主机可达,而且说明目的主机与源主机之间的路由器工作正常,源主机和目的主机的IP、ICMP软件运行正常。但若在传输过程中了出现了某些问题,如网络不通等,导致数据被定向到一个无效的目的地,这时相关路由器或目的主机将发回目的不可达报文(类型为3),并在代码中说明该报文的具体情况:是网络不可达还是主机不可达等。若请求报文在传输过程中超时,即TTL被减为0(报文每经过一个路由器TTL都要减1),则该路由器返回一个TTL超时报文(类型为11),报文IP头中源IP地址即为本路由器的IP地址。
五、添加代码
在完成了对各控件的设置和类的添加以后就是对代码的编写了,这里给出了新建类CICMP和RouteTraceDlg.cpp的代码,详细代码请参看源程序。
ICMP.cpp文件代码:
|
// ICMP.cpp: implementation of the CICMP class. #include "stdafx.h" #ifdef _DEBUG ////////////////////////////////////////////////////////////////////// CICMP::CICMP() m_pIp = (IP_HEAD *)new BYTE[MAX_PACKET]; } CICMP::~CICMP() BOOL CICMP::Initialize() int timeout =5000; return TRUE; void CICMP::Uninitialize() //释放Socket USHORT CICMP::CheckSum(USHORT *buffer, int size) //计算校验和 cksum = (cksum >> 16) + (cksum & 0xffff); return (USHORT)(~cksum); BOOL CICMP::SendICMPPack(char *pAddr) return SendICMPPack(&sockAddr); //填充数据 //校验和 if(state == SOCKET_ERROR) { if(state <DEF_PACKET) { return TRUE; //----------------------接收数据---------------------------- addr = inet_ntoa(m_sockAddr.sin_addr); if (state == SOCKET_ERROR) { //分析数据 if (state < (ipheadlen+MIN_PACKET)) { ICMP_HEAD * p_icmprev; switch (p_icmprev->type) } RouteTraceDlg.cpp文件代码:// RouteTraceDlg.cpp : implementation file
///////////////////////////////////////////////////////////////////////////// CEvent eventStopRoute; CICMP m_icmp; return 0; …… //系统代码 BOOL CRouteTraceDlg::OnInitDialog() …… //系统代码 ListView_SetExtendedListViewStyleEx(m_list.m_hWnd, LVS_EX_FULLROWSELECT, 0xFFFFFFFF); return TRUE; // return TRUE unless you set the focus to a control …… //系统代码 void CRouteTraceDlg::OnTrace() if(str.IsEmpty()) { m_list.DeleteAllItems(); void CRouteTraceDlg::OnStop() void CRouteTraceDlg::OnDestroy() |
代码运行效果图如下:
源代码下载
六、结束语
本文所述程序在 Windows 98 下 Visual C++6.0 中调试通过,并在宽带网中测试成功。读者可根据实际需要修改程序中的参数,以实现更强大的功能,比如可以把超时值设置成更合适的值,或设置成可动态输入的形式,示例程序请看本文所附源码。
七、参考文献
1. 胡晓军、邓波、高宏伟 编著 Visual C++高级开发范例解析 2002.1 电子工业出版社
2. 周明天、汪文勇 编著 TCP/IP网络原理与技术 1993.12 清华大学出版社
浙公网安备 33010602011771号