TCP/IP协议详解卷1-ping,traceroute程序

类别:软件工程 点击:0 评论:0 推荐:
 卷1第七、八章
第七章是Ping程序的基本原理,第八章是traceroute( Win2000下是tracert)的原理。主要介绍的是一些原理性的东西,并以实际的tcpdump的抓包的内容作解释。
ping 程序是利用icmp的回复请求来探测远端主机是否可达。(并不能继续判断端口是否可达。要想查看端口,就要使用扫描器了。)win2000里的网络库里已经提供网络函数库(icmp.dll)可以实现利用icmp来探测远端主机。相比起使用管道来读ping的结果,或者嵌入ping源码,这个是最简单的方法了(没办法,人懒)。ping其实还有一个R选项,用来记录经过的路由,以前一直不知道。(ping www.google.com -r 7)记录经过的7个路由器。按照分析,根据所在环境限制最多可以记录8~9个项目。
除了回显请求外,还可以利用icmp来实现时间请求。在icmp的数据包中可以包含发送时间,目的主机收到后再附上自身当时时间才发回。这样可以做一个时间校验,并可以判断源与目的之间的通讯速度。由于具体的内容部分比较烦,类型太多,一下子记不住各个类型的意思。
一般用ping的时候只是用了它的最简单的功能:检查主机能不能连到。其实使用它所提供的其他选项,可以实现许多细节上的控制,例如数据包长度,TTL,路由记录,宽/严路由经过路由等。 tracetroute,也就是 trace route,跟踪路由。这个程序最早是Van Jacobson实现的。源码在网上可以找到,不过我还没有去找。主要的原理是IP路由过程中对数据包TTL(Time to Live,存活时间)的处理。当路由器收到一个IP包时,会修改IP包的TTL(及由此造成的头部检验和checksum变化)。每收到一个包,检查这个的TTL是否是0或1。如果是,表明这个包还没有到达目的地,而且剩余时间不多了,肯定是到不了目的地了。这样路由器就简单地丢弃这个包,并给源主机发送 ICMP通知,说这个包已经超时了。ICMP的通知信息里包含当前路由器发送时所用的IP。
这样就可以通过构造数据包,来间接检查到达一个主机时经过了哪些路由。一开始发送一个TTL为1的包,这样到达第一个路由器的时候就已经超时了,第一个路由器就发通知说包超时,这样就可以记录下所经过的第一个路由器的IP。然后TTL加1,安全通过第一个路由器,而第二个路由器的的处理与第一个相同,丢包,发通知说包超时了,这样记录下第二个路由器IP,由此可以一直进行下去,直到这个数据包到达目标主机,由此打印出所有经过的路由器。
在通信中,IP层只负责数据的路由与传输,并不处理数据包的内容。例如ICMP,或TCP,UDP,这些协议是依赖IP层的传输功能来传送数据的。在通信双方的主机中,收到这些协议的数据包后,一般在通信的对应主机上,会有程序来处理这些数据。而直接的IP数据报是没有用处的(win2000的驱动层可以直接使用IP报而不需要加上其他协议,但是一般是不会这样用的)。因此traceroute程序发送一个UDP包来试探。对路由器来说,UDP数据报只是IP数据报的一种,它并不关心UDP数据报的具体内容。直到这个包到达目的端的主机会,目的主机的内核会解析UDP数据报,并查找数据报中要求端口是否已经有进程在使用。如果找到,则通知进程有数据到达。而如果找不到,则发送一个“目的端口不可达”的ICMP错误数据回到源主机。
这样就可以完全确定下来。trcertroute建立一个UDP数据包,不断修改TTL值并发送出去,如果收到“超时错”,表示刚刚到达的是路由器,而如果收到的是“端口不可达”错误,表示刚刚到达的就是目的主机。这样路由跟踪完成,程序结束。
有几个细节:
1.局域网的路由是相对稳定的,因此用traceroute打印出来的响应时间相差不大。而如果用来跟踪广域网的路由,由于广域网的路由信息是动态变化的,而且并不能确定是发送路径耗时还是返回路径耗时较多,因此时间与路由信息只能做为参考。
2.TTL 的选择。如果把TTL设得足够大,是不是一定可以打印出所有路由,比如一个数据包经过300个路由器才到达目的端。当然在现有网络环境下不太可能出现要经过这么多路由的情况。而TTL信息在IP数据报中只有一个字节,也就是最多能设定到255(256以后又重新从0开始)。设定这个信息的目的,就是防止一些僵而不化的数据报在网络漫上无目的的游荡而不消失。数据报每经过一个路由器,路由器就把TTL减1(或在该路由器被处理前经过的秒数),总有一个时候会被减到1,然后路由器会把它丢弃。
3.traceroute的是以收到“端口不可达”为标志来结束的。前提是发出的UDP数据报中要求的端口在目的主机上没有进程在使用。而如果目的主机上正好有进程在使用这个端口,接收这个包并按正常方式处理,这样traceroute就收不到“端口不可达”的错误了。为了避免出现这种情况,UDP数据报的端口很高(书中的实现是初始值33435,以后每发送一次再加1,端口号最大可以到65535)。普通程序一般不会使用这些高端口。问题是假如真的存在这种情况时,traceroute会怎么处理?而好像Solaris系统可能会使用高端口,这时又怎么样。
4. 在发送过程中,要经过许多的路由,到达目的主机前,可能还要经过网关,防火墙,以及其他例如IDS的过滤,发送包能不能到达目的主机还是个问题。而即使到达了,发送的ICMP信息能不能返回也是个问题。因为沿途经过的关卡太多,遇上黑洞路由器,不转发这些信息的话,那就一点办法也没有了。
书中还提到原来的traceroute里有一个选项,可以指定数据包经过的路由器。如果是宽路由,则只要经过指定的路由即可。而如果是严路由,则必须按指定的顺序经过指定的路由器。因为这个选项可能导致某个固定的路由处理信息太多,在公布的源码里已经取消了。但是可以找到补丁,还是可以用起来的。从比较的结果看,似乎指定路由器反而不如让路由器采用默认路由处理得快。而对于严路由来说,要成功就要更难一些,因为并不一定你指定的路由器正好有条目到接下来的路由器。 这一章的习题比较复杂,找不到网络环境可以实验,而照原理分析看不出究竟。源码没有,如果真的有,现在的水平估计也看不出什么东西来。先不求甚解吧,看下一遍的时候可能就知道了。

本文地址:http://com.8s8s.com/it/it35763.htm