新年快乐,继续来部分粘贴复制我的这一系列文章啦,如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)star我的这一系列文章,虽然说现在这种“看不见”的东西真正能在实用中遇到的机会不多,但是我始终觉得无论计算机的语言,热点方向怎么变化,作为一个程序员,很多基本的知识都应该有所了解。而当时在网上搜索资料的时候,这方面的资料真的是少的可怜,所以,我有幸前两年接触了这方面的知识,我觉得我应该把我知道的记录下来,虽然写的不一定很好,但是希望能给需要帮助的人多个参考。我的计划是用半年时间来写完这一系列文章,这个标题也是我对太多速成文章的一种态度,好了,废话不再多扯了,下面是其中的一节内容,更多内容可以去gitbook上找到。

TraceRoute 是另外一个利用ICMP的程序,目的为了找到一个端点到另一个端点的路线,其设计理念我个人是觉得十分的巧妙。而且这个程序在windows和linux上还使用了稍微有点点不同的方法,但是却可以看到有异曲同工之妙的地方。

TraceRoute的起源

TraceRout这个网络工具主要是由一个叫Van Jacobson的大牛完成的,这位大牛应该算是互联网名人堂级人物,他最出名的应该是提出了TCP里面的Jacobson算法用以解决拥塞问题,而这个算法在今天百分之九十的TCP终端上面都在运用。 1987年,他在另外一位大牛Steve Deering的建议下写了这样一个探测网络路径的工具。同样,在第二大部分,程序的时候,我会用raw socket写一个玩具版的traceroute程序,来阐述其基本原理。

TTL和ICMP在windows上的结合

在介绍IP头格式的时候,里面有一个字段叫TTL,Time to live,这个字段起初是规定一个IP数据包在网络中的生存周期的,防止一个数据包无限制占用网络资源,毕竟要想一切有秩序,一个上限是不可避免要设置的,所谓的红线就是这个道理。而随着网络基础设施的升级和网络规模的增长,连接每个网络的路由器处理一个数据包的时间基本都远远小于1秒钟,而数据包在路由器之间的网线的上的传输时间更是可以忽略不计,所以这个字段就演化成了经过多少个路由器的计数器。每经过一个路由器,TTL的值就会减1,当这个值为0的时候,也就是这个IP数据包消亡的时候。

比如举个例子,如果某个IP包中TTL设置为1,那么这个数据包就只能在这个一个子网内传输,因为一旦经过了一个路由器,TTL就会变成0,该数据包就会消失了。而当这个数据包消失的时候,一个ICMP消息就会被产生,在上个部分里表里,ICMP头里的Type值为11的时候表示超时,而这个就是当TTL为0的时候被回复的ICMP消息。Windows 的TraceRoute程序就是利用了这个原理,先还是来看一下windows上运行traceroute是啥样的,不过windows的traceroute程序真名叫tracert,其运行结果如下:

我寻找的是从我这里到局域网的某一个路由器的地址,可以看到,从我的主机到这个路由器要经过三个路由器,所以有三行输出,而每行有三个往返时间,这是因为traceroute会发三次ICMP的echo消息,而这个输出值得我们逐行分析一下。

第一行是到我的局域网路由器(热点),往返时间是6-8ms之间,这个时候TTL被设置成1,从下面抓到的数据包中可以看到其具体的数据:

从截图中可以看出,第一个数据包TTL是1,虽然dest IP是100.97.2.9,但实际上在192.168.8.1这个路由器中这个数据包就已经消失了,因为这个时候该IP数据包中的TTL的值已经减为0,192.168.8.1随即回复一个ICMP消息报告超时。上一节中介绍了ICMP echo的格式,非常简单,而ICMP超时的数据包的格式比Echo稍微多一点点信息,但是依然是并不复杂,其格式如下:

其中前4个字节和echo是一样的,只不过这里type变成了11(十进制)标识超时错误消息,code为0表示ttl为0发生了超时。接下来4个字节作为保留字节根本没有用处,目的是和所有ICMP报文格式统一并兼容。而接着后面的数据部分就和echo不同了,而这些被选择中的数据也是这个数据头格式的精妙之所在。ICMP的超时消息会把发送方的IP数据头和IP数据包中头64个bit作为数据部分传回给发送方。其作用是可以让发送方的更上层的进程在如有需要的时候筛选出自己需要的信息和数据包。比如说,有了这个部分,里面就有了IP头中的TTL信息,发送端就知道是第几个TTL到期,数据包消失的。而接着的64个bit的数据在特定情况下更是有妙用,特别是在后面要介绍的端口不可达的ICMP消息之中。

第二行就是TTL为2的回复,而这一行全是星号,这是因为有的网关/路由器不会返回ICMP超时报文,甚至为了安全考虑,很多带有防火墙的路由器不返回各种ICMP报文,所以你会看到上面输出的星号,而这种暂时的不返回并不妨碍继续向更深的一层探测,所以在三次没有返回后,traceroute会将TTL递增1,继续发送ICMP的echo报文。

第三行就是TTL为3的结果,而这个时候数据包已经到达目标网络,由于探测的时候发的是ICMP echo request的消息,所以这个时候发送端可以得到ICMP echo reply消息,具体请参见上一节(你到底在ping什么)。所以发送端就能知道他的数据包已经到达了目的地,也就不会再继续增加TTL,探测活动停止,这个从抓获的数据包中也能得到体现。

TTL和ICMP在linux上的结合

前面说过traceroute这个程序在linux上和windows上采用一个有一点点不一样的设计,但是都是利用了ICMP消息和TTL。

Linux上traceroute程序就是使用traceroute这个命令,看起来像句废话,而linux上追踪数据包路径的方法是采用的UDP,而不是ICMP的echo消息。这样的一个不同点就是,使用UDP的时候,如果对方的端口是没有的,那么ICMP就会返回端口不可达消息,type是3。而在linux上会在这个UDP消息中使用一个30000以上端口号,这样当时数据包到达目的主机的时候,由于对方主机并没有打开这个UDP端口,所以ICMP会返回一个端口不可达的消息,这样发送端收到端口不可达的时候就知道不需要继续探测le。其格式和超时的格式是一模一样的,不同点只是type的数值是3,code的数值3标识端口不可达。

其余中间的探测过程和windows一样,都是使用ICMP的超时消息。

这里我想要稍微更多的介绍一下端口不可达的ICMP消息之中的data部分了,这个部分包含IP数据头和IP数据包的前8个字节,那么如果发送端发送的是UDP消息的话,回一下前面介绍的UDP头的格式,前8个字节正好UDP的头部,其中含有发送端的Port的到达端的Port,而UDP是IP的data部分,所以说发送端就可以从这个ICMP的错误消息中得到更多的信息。从下面这个抓包中可以看出这样一个data的返回(忽略port号,哈哈):

传统的traceroute利用ICMP消息有很多弊端,其中之一就是前面说的有很多网关或者路由器由于安全的设置不会返回任何ICMP错误消息,所以现在也有很多探测方法是利用TCP,有兴趣可以去搜索一下。

三十天学不会TCP,UDP/IP网络编程-TraceRoute的哲学的更多相关文章

  1. 三十天学不会TCP,UDP/IP网络编程-IP头格式祥述

    我又来了,这篇文章还是来做(da)推(guang)介(gao)我自己的!俗话说事不过三,我觉得我下次得换个说法了,不然估计要被厌恶了,但是我是好心呐,一定要相信我纯洁的眼神.由于这两年接触到了比较多的 ...

  2. 三十天学不会TCP,UDP/IP网络编程-ARP -- 连接MAC和IP

    继续来做(da)推(guang)介(gao)我自己的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,目前已完成 ...

  3. 三十天学不会TCP,UDP/IP网络编程 -- RTT的计算

    欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)看到完整版. 如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,虽然说现在这种“看不见”的 ...

  4. 三十天学不会TCP,UDP/IP网络编程 - 绅士的开始

    经过了过年的忙碌和年初的懈怠一切的日子,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关 ...

  5. 三十天学不会TCP,UDP/IP网络编程-UDP,从简单的开始

    如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)star我的这一系列文章,虽然说现在这种 ...

  6. 三十天学不会TCP,UDP/IP网络编程 - RST的用法

    不知不觉也写了这么多了,继续我的自己的推广大业~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关的计算机网络知识,和对计算机 ...

  7. 三十天学不会TCP,UDP/IP网络编程 - UDP的实践--DHCP

    在经历了一顿忙碌加出去玩了玩之后,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到,在gitbook的后台流量 ...

  8. 三十天学不会TCP,UDP/IP网络编程 -- TCP中的智慧之连续ARQ

    突然发现上一篇文章贴图有问题,关键我怎么调也调不好,为了表达歉意,我再贴一篇gitbook上的吧,虽然违背了我自己的隔一篇在这里发一次的潜规则~其余完整版可以去gitbook(https://www. ...

  9. 三十天学不会TCP,UDP/IP编程--MAC地址和数据链路层

    这篇文章主要是来做(da)推(guang)介(gao)的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会 ...

随机推荐

  1. GC 基础(转)

    转自:http://blog.csdn.net/ning109314/article/details/10411495/ = GC 基础 ===================== JAVA堆的描述如 ...

  2. Makefile中的变量和shell变量

    我们在写makefile时 多多少少会用到shell脚本, 对于变量的在shell中的使用有一些要注意的细节.让我们从一个简单的makefile来看看. 注意makefile中一定要有一个目标,且一定 ...

  3. 利用python web框架django实现py-faster-rcnn demo实例

    操作系统.编程环境及其他: window7  cpu  python2.7  pycharm5.0  django1.8x 说明:本blog是上一篇blog(http://www.cnblogs.co ...

  4. windows平台下基于QT和OpenCV搭建图像处理平台

        在之前的博客中,已经分别比较详细地阐述了"windows平台下基于VS和OpenCV"以及"Linux平台下基于QT和OpenCV"搭建图像处理框架,并 ...

  5. hiho-1015- KMP算法

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  6. Ubuntu 环境 TensorFlow (最新版1.4) 源码编译、安装

    Ubuntu 环境 TensorFlow 源码编译安装 基于(Ubuntu 14.04LTS/Ubuntu 16.04LTS/) 一.编译环境 1) 安装 pip sudo apt-get insta ...

  7. flask_login 整合 pyjwt + json 简易flask框架

    现在很多框架都实现前后端分离,主要为了适应以下几个目的: 1,前后端的分离,可以使前端开发和后端开发更加分工明确,而不是后端还需要在视图模板中加入很多{% XXXX %}标签 2,是为了适应跨域调用或 ...

  8. MySQL安装出现的1045问题以及解决方法

    MySQL安装出现1045的问题解决办法: 1045.的原因是已经装过了MySQL再次装的时候报的错误,那么该怎么处理那??? 首先卸载程序,从windows里找到mysql右击卸载,然后就是在dos ...

  9. always中的敏感变量

    always语句下如果有判断语句if,那么if语句中的条件必须有always中的敏感变量. 否则错误提示为:Error (10200): Verilog HDL Conditional Stateme ...

  10. JAVA入门[10]-mybatis分页查询

    1.添加分页插件 在mybatis-generator-config.xml添加plugin节点: <plugin type="org.mybatis.generator.plugin ...