基于淘宝IP地址库的图形界面traceroute程序的设计与实现
2014-03-01张亮
张 亮
(扬州工业职业技术学院电气信息工程学院 江苏扬州 225127)
0 引言
在网络管理和维护工作中,操作系统自带的traceroute工具是最常用的基本工具之一,通过这一工具,网管可以清楚地查看从当前主机访问Internet上的任意目标主机时所经过的路由IP地址以及到每一跳路由所产生的网络延时。然而,无论是Windows操作系统还是Linux操作系统,所提供的traceroute工具均基于终端命令行界面,使用不是很方便,且该工具完全依靠反向DNS来查询每一跳路由IP所对应的域名,国内运营商路由一般极少提供反向DNS查询支持,因此traceroute命令无法显示出每一跳路由所对应的运营商及所处地区,当对广域网路由进行查询,特别是对跨运营商网络路由进行查询的时候,使用十分不便。因此,本文对traceroute工具的原理进行了分析,并利用C#和.NET平台,设计和开发了一个基于图形界面的traceroute程序,在实现traceroute程序功能的基础上,利用淘宝网提供的IP地址库和Web Service API接口,对每一跳路由IP地址进行查询,显示该IP地址所对应的运营商及所在地区。实践证明,该工具比操作系统自带版本使用更加方便和直观。
1 traceroute原理
目前,Windows操作系统及Unix、Linux操作系统都自带traceroute工具(在Windows操作系统上名称为tracert),其实现原理均基于ICMP协议,但细节有一定区别。在Windows系统上,tracert工具的实现是基于 ICMP Echo Request,Echo Reply和 TTL-expired的,具体来说,当源主机使用tracert命令来探测前往目标主机的路由时,源主机会按顺序发出最多30个ICMP Echo Request数据包,并将第一个数据包的TTL值设为1,第二个数据包的TTL值设为2,并依此类推。路径中的第n个路由器会接收到源主机发送的第n个ICMP Echo Request数据包,并因为TTL已经减为0而向源主机发送ICMP TTL-expired数据包,这样源主机就得到了该跳路由器的IP信息和数据包往来需要的时间。当目标主机收到最后一个ICMP Echo Request包时,会发回type为0的ICMP Echo Reply包,当源主机收到此包时,就知道目标主机已经到达,从而结束发送 ICMP Echo Request数据包,tracert命令结束[1]。在 Unix和Linux系统上,当源主机使用traceroute命令时,会按顺序发出目标UDP端口号大于32768的UDP数据包,同时TTL从1开始递增,和上文原理一样,中间的路由器送回 ICMP TTL-expired数据包,而目标主机会送回ICMP port unreachable数据包(因为没有任何应用程序会使用大于32768的端口号)[2]。从上述原理可以看出,只要任何一跳路由器设置不发送ICMP TTL-expired数据包,该跳路由的信息就无法获得,这就是为什么在实践中使用traceroute命令的时候总有一跳或多跳路由显示“请求超时”的原因。
2 系统实现
本系统开发环境为Windows 7 32bit中文旗舰版,使用VS2012旗舰版开发平台,在.Net 2.0环境下使用C#语言开发Winform程序。
2.1 Winform 实现
本程序初始版本侧重于功能实现,图形界面设计得较为简洁,在主界面上使用一个TextBox控件来输入目标主机的IP地址或域名,使用一个ListBox控件来显示结果,一个Button控件来控制程序运行。程序设计时,考虑到探测每一跳路由均需要一定的时间,并且可能超时无法显示结果,因此适宜采用多线程程序设计方法。具体来说,就是将响应Button控件Click事件的代码单独放到一个线程中运行。这样的好处是即使线程因为网络超时发生阻塞,也不会影响主线程的运行。否则,如果采用单线程设计的方式,当网络超时发生时,主线程会被阻塞,整个图形界面会卡死,从而严重影响用户的使用体验。另外,本程序主要在Windows平台下运行,因此选择采用发送ICMP Echo Request包的方法来实现路由跟踪。程序主要实现步骤如下:
①定义ICMP类:根据ICMP协议规定,实现ICMP类相关字段和操作方法。
②创建Raw Socket:因为ICMP数据包是直接打包在IP包中进行发送的,因此程序中如果想收发ICMP包,必须创建Raw Socket。在C#中,可以采用下列代码创建:Sockets=new Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.Icmp)。需要注意的是,微软在Windows 7操作系统中加强了对安全性的控制,程序运行时默认权限为非管理员权限,而创建Raw Socket需要管理员权限,因此在程序编译成功后需要使用管理员权限来运行,如果想让程序在启动时自动要求管理员权限,可以修改app.manifest文件中的配置项,如在Windows XP平台下运行程序则无此问题。
③获取目标主机IP:使用系统提供的Dns类的Resolve方法对用户输入的域名或者IP进行解析,并打包成IPEndPoint类,便于后续发送数据包。需要注意的是,有一些网站的域名对应多个IP地址,在程序中,统一使用返回的第一条IP地址。
④构造ICMP数据包:利用前面定义的ICMP来构造ICMP数据包。由于发送的是ICMP Echo Request包,因此在构造数据包时,需要把type字段值设为8,code字段设为0,标识符和序列号字段可以任意设置,校验和字段先设为0,在其他字段设置完毕后,通过协议规定的校验算法进行计算,用得到的值设置该字段,具体可参考ICMP协议。
⑤将ICMP打包到IP包中进行发送:通过for循环控制,发送TTL从1开始递增的IP数据包,因为网络路由一般不可能大于30跳,所以程序最多循环发送30次。在每次发送之前,需要通过设置Socket的SetSocketOption方法对数据包的属性进行设置,具体来说,可以通过SetSocketOption(SocketOptionLevel.IP,SocketOptionName.
IpTimeToLive,ttl)来设置本次包的TTL值,通过 SetSocketOption(SocketOptionLevel.Socket,Socke-tOptionName.SendTimeout,10000)和 SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,10000)来设置发送和接收超时时间,本程序都设为10 000 ms。另外,在发送之前需要通过DateTime.Now来获取当前系统时间,当对应的包返回时,再次获取系统时间从而计算出RTT值。
⑥将结果在 ListBox控件显示:通过 Receive-From(ByteRecv, ByteRecv.Length, SocketFlags.None,ref epSRC)方法接收返回的ICMP数据包,如果超过规定的时间没有接收到回应,则直接通过continue语句进行下一次循环,并在ListBox控件中显示此跳路由超时。如果正常接收到回应,则通过ref epSRC引用变量获取该跳路由IP,并通过list-Box.Items.Add方法将该条信息添加到ListBox控件中。最后,需要判断此次接收到的ICMP包的type是否为0,如果为0,则说明此次接收到的已经是ICMP Echo Reply包,目标主机已到达,循环结束,否则继续循环,将TTL加1后发送下一个ICMP Echo Request数据包。
2.2 淘宝IP地址库简介
通过上述程序步骤,已经实现了带图形界面的traceroute程序的基本功能,但和系统自带的程序一样,还无法显示每一跳路由IP地址对应的信息。如果需要解析IP地址的信息,需要有一个IP地址信息数据库才可以实现,目前中国各运营商并无官方数据提供,想实现这一功能,只能通过第三方数据实现,淘宝IP地址库(http://ip.taobao.com)是目前比较好的选择。为了实现对淘宝用户访问来源的精确定位,淘宝网收集了中国大陆及海外各大运营商的IP地址数据,根据淘宝自身统计,目前其数据库对IP地址来源国家的识别准确度达到100%,中国大陆省准确度超过99.8%,市准确度超过96.8%,运营商准确度超过94.3%,可以说数据质量相当高,完全能满足需求。更为重要的是,淘宝IP数据库完全通过Web Service的方法对外提供免费服务,只需调用淘宝提供的Web API,即可得到IP地址对应的信息,本地程序无需下载数据库文件,使用十分方便。
2.3 使用淘宝IP地址库进行IP解析
使用淘宝IP地址库进行IP地址解析非常简单,只需使用GET方式调用淘宝提供的URL:http://ip.taobao.com/service/getIpInfo.php?ip=[ip 地址字串]即可。该接口返回的信息为JSON格式,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。如对IP地址222.189.131.215进行查询,调用 http://ip.taobao.com/service/getIpInfo.php?ip=222.189.131.215,返回的结果为{"code":0,"data":{"country":"u4e2du56fd","country_id":"CN","area":"u534eu4e1c","area_id":"300000","region":"u6c5fu82cfu7701","region_id":"320000","city":"u626cu5ddeu5e02","city_id":"321000","county":"","county_id":" -1","isp":"u7535u4fe1","isp_id":"100017","ip":"222.189.131.215"}},其中“code”的值的含义为 0:成功,1:失败。而"country"、"region"、"city"、"isp"则分别对应国家、省、市和运营商,它们的值都用Unicode进行了编码。对应到程序,只需要将2.1节中的第⑥步进行改进,当通过ref epSRC引用变量获取某跳路由IP后,可通过HttpWebRequest类发起GET请求,并通过HttpWebResponse类来获取返回的输入流,从而读取出淘宝API返回的JSON格式的数据。需要注意的是,.NET 2.0平台本身并不带有对JSON格式数据进行解析的类库,需要通过第三方类库来进行解析。本项目选择采用著名的Json.NET 4.5 版本来进行 JSON 解析,Json.NET 性能强大,使用方便,可以便捷地将JSON数据转换成.NET类,或者可以直接手动对JSON各个String对应的Value进行操作,限于篇幅,具体API操作可参考该类库的主页http://json.codeplex.com/
2.4 测试运行
将代码编译生成可执行文件后,在扬州电信宽带网络环境下对软件进行了测试,如对江苏移动官网进行追踪,结果如图1所示。
可以看到,从扬州电信宽带网络访问江苏移动网络,需要经过电信骨干网,然后通过网络互联互通中心进入中国移动骨干网,从而最终访问到江苏移动官网目标服务器。通过图1也可以清楚直观地看出,当数据包在电信骨干网和移动骨干网内进行传输的时候,延时都非常小,主要延时来自从电信骨干网进入移动骨干网的那一跳路由,由此也证明了互联互通带宽不足仍然是造成不同运营商网络互访缓慢的主要原因。
图1 程序主界面
3 结束语
本文提出并实现了一个基于图形界面的traceroute程序,使用简便,并且能根据淘宝IP数据库提供的数据来解析路径中每一跳路由IP地址的对应信息,为网管员快速对网络路由状况进行诊断提供了帮助,同时对同类系统的实现也有一定的参考作用。
[1] 宋凌怡.网络管理系统中Ping和Tracert功能的实现[J].赤峰学院学报:自然科学版,2011(7):29-30.
[2] 庄晓华.ICMP协议的应用及分析[J].济南职业技术学院学报,2011(5):58-60.