标签:tcpip traceroute tracert 网络探测 icmp
搭建网络环境的时候,经常有想要知道报文从源到目的所经历的所有路由节点这样的需要。此时,traceroute小程序,后续简称为tracert,就有用武之地了。
tracert,最初由大神Van Jacobson设计并实现(膜拜),可以用来探测出报文在网络中从源到目的所经过的所有三层路由节点。
既然tracert用来探测路径,那么问题来了:它如何确定路径?
我们知道IP报文头有一个ttl字段,用来确定IP报文的存活时间。每经过一次转发,ttl数值减一,当ttl为0时,如果报文还没有到达目的,那么协议栈就会向源端回应一个ICMP ttl超时报文。知道了这个东东后,确定路径是否就有眉目了呢?
(1)向目的发送ttl=1的UDP报文,第一个路由节点收到报文后发现ttl=0,向源端回应一个ICMP ttl超时报文,源知道了第一个路由节点。
(2)向目的发送ttl=2的UDP报文,第一个路由节点收到报文后ttl=1,继续转发给第二个路由节点,第二个路由节点收到报文后ttl=0,向源端回应一个ICMP ttl超时报文,源又知道了第二个路由节点。
(3)向目的发送ttl=3的UDP报文……
通过上面步骤可以一直发送UDP报文直到报文到达目的,那么问题来了:
(1)挖掘机技术哪家强?
(2)源如何知道报文到达了目的并停止发报文?
关于问题(1),我想大家都知道那是布鲁西特大学(blue shit)最强。
接下来重点介绍问题(2)。
我们又知道,UDP报文头有一个字段叫目的端口,用来告诉目的端这个报文要请求的是哪个服务。当目的端服务(端口)不存在时,协议栈会向源发送一个ICMP端口不可达报文,告诉源,哥没这服务,别来烦哥。源又知道了目的是不是,呵呵。
好,到此为止,问题完美解决。嗯?是不是有点不对?是的,你的疑惑没有错:tracert这小贼从头到尾都在发没用的报文,欺骗了网络中兢兢业业工作的路由兄弟们的感情,成功窃取了报文从源到目的的路径。
单纯从IP报文的角度来说,四层协议常用有三中:ICMP(经常被认为是三层协议,why,不告诉你),UDP,TCP。
前面我们介绍从源发送的是UDP报文,那么能否用ICMP或者TCP报文替换?答案必须是肯定的,否则哪里来的乐趣?
确定路径的原理和前面一致,利用ttl超时。那么如何确认到达了目的?
想想ping程序的实现:发送ICMP echo报文,回应ICMP echo reply。
非常好,源持续向目的发送ttl递增的ICMP echo报文:收到ICMP ttl超时报文时认为是路径上路由节点,收到ICMP echo replay时认为到达了目的。
首先要明确的原理肯定和前面一致;其次要明确的是肯定不能直接发送TCP报文,why?
TCP是面向连接的协议,发送TCP报文首先要和目的建立连接,tracert小贼哪里知道目的端有虾米服务。就算知道某个目的端有虾米服务,但是换个目的端咋办?不通用了不是,这便如何是好?
办法呢都是憋出来的,硬憋肯定能憋出来。
先来想想为啥不能发TCP报文,因为发报文前要先建立连接。我说我不建,你偏要我建,哼!
那连接咋建立的?三次握手。啥叫三次握手,简单来说跟好基友的形成过程一样一样的:
就是这么简单,so easy,一对好基友非常友好非常暧昧的正式开始交往。
回到正题:既然不能发TCP报文的原因是它要先建立连接,那么,为了阻止你,哥就不让你好好建。
小贼tracert直接开始第三次握手。也就是说,源向目的发送“恩,好!(ack报文)”这个消息。
目的端收到这个消息后心想,哪个白痴连握手都不会。然后它就告诉源咱俩得重新开始握手(rst报文)。
好了,问题解决:源持续向目的发送ttl递增的ack报文,收到超时回应后认为是路径上的路由节点,收到rst报文后认为到达目的端。
备注:
1. UDP及ICMP方式实现的tracert是经过先贤们验证的可行方案,TCP方式是我自己琢磨出来的,还未实现,不确定能否成功,需要实现验证一下。
2. 具体的实现代码(c语言)等我完成后会贴出来。
标签:tcpip traceroute tracert 网络探测 icmp
原文地址:http://blog.csdn.net/chrisun157/article/details/44986337