第7章 Ping程序和traceroute程序
Ping程序
ping程序编写的目的是为了测试另外一台主机是否可达。程序发送的是一份ICMP回显请求报文给目的主机,并等待ICMP回显应答。
一般的TCP/IP实现都在内核中直接支持ping服务器——这种服务器不是一个用户进程,响应ICMP报文的是内核程序。
Ping中的报文往返时间是如何计算的?
ping程序在ICMP报文数据中存放发送请求时的时间值,在未来接收到该报文的回显时,用当前时间减去回显报文中之前保存过的时间,得到的就是往返时间值了。
ping一个环回网址和ping主机的IP地址有什么不同?
例如:考虑这么一个情况,主机的IP地址是192.168.1.230,而我们都知道127.0.0.1属于一个环回地址。ping这两个地址会有什么不同?
首先我们要了解一下,ICMP报文是在IP数据报内部的,ICMP需要借住IP的选路才能在互联网中工作。当ping程序向某个地址发送ICMP报文时,会先把ICMP报文打包成一个IP数据报,再通过IP数据报去进行转发。

参考一下环回接口处理IP数据包的过程

如图,ping 127.0.0.1的数据报在IP层中就会被放置到环回驱动程序中,随后就会被放回IP输入队列中,而192.168.1.230的报文会按照一般的IP地址数据下放到以太网驱动程序中去,并且由其中一段代码做判断,最后才回放到IP输入队列中。两个过程的区别在于,一个ping程序的数据会下放到以太网驱动程序,一个则直接回送。在网络层会把环回驱动程序和以太网驱动程序看作不同的链路层。
一、同一网段内
首先,如果主机A,要去ping主机B,那么主机A,就要封装二层报文,他会先查自己的MAC地址表,如果没有B的MAC地址,就会向外发送一个ARP广播包,如图:

其中ARP报文格式如下:
其中OP
1:表示ARP请求
2:表示ARP应答
3:表示RARP请求
4:表示RARP应答
首先,交换机会收到这个报文后,交换机有学习MAC地址的功能,所以他会检索自己有没有保存主机B的MAC地址,如果有,就返回给主机A,如果没有,就会向所有端口发送ARP广播,其它主机收到后,发现不是在找自己,就纷纷丢弃了该报文,不去理会。直到主机B收到了报文后,就立即响应,我的MAC地址是多少,同时学到主机A的MAC地址,并按同样的ARP报文格式返回给主机A。如图:

当主机B收到了这个报文后,发现是主机A 的ICPM回显请求,就按同样的格式,返回一个值给主机A,这样就完成了同一网段内的ping过程。

在这里,讲了这么久的局域网内的PING,实际过程的发生不到1毫秒。
二、不同网段内
如果主机A要ping主机C,那么主机A发现主机C的IP和自己不是同一网段,他就去找网关转发,但是他也不知道网关的MAC地址情况下呢?他就会向之前那个步骤一样先发送一个ARP广播,学到网关的MAC地址,再发封装ICMP报文给网关路由器.。报文格式如下:

当路由器收到主机A发过来的ICMP报文,发现自己的目的地址是其本身MAC地址,根据目的的IP2.1.1.1,查路由表,发现2.1.1.1/24的路由表项,得到一个出口指针,去掉原来的MAC头部,加上自己的MAC地址向主机C转发。(如果网关也没有主机C的MAC地址,还是要向前面一个步骤一样,ARP广播一下即可相互学到。路由器2端口能学到主机C的MAC地址,主机C也能学到路由器2端口的MAC地址。)报文格式如下:

最后,在主机C已学到路由器2端口MAC地址,路由器2端口转发给路由器1端口,路由1端口学到主机A的MAC地址的情况下,他们就不需要再做ARP解析,就将ICMP的回显请求回复过来。报文格式大致如下:

Traceroute
Traceroute(linux)/tracert(win) 均是用于同一目的的网络调试工具。它们用于显示数据包在IP网络中经过的路由器的IP地址。
原理
这些程序是利用IP数据包的存活时间(TTL)值来实现其功能的。
当一台计算机发送IP数据包时,会为数据包设置存活时间(TTL)值。每当数据包经过一个路由器,其存活时间值就会减 1。当存活时间减到 0 时,路由器将不再转发数据包,而是发送一个 ICMP TTL 数据包给最初发出数据包的计算机。
Traceroute 程序首先向目标主机发出 TTL 为 1 的数据包,发送数据包的计算机与目标主机之间的路径中的第一个路由器,在转发数据包时将数据包的 TTL 减 1,它发现 TTL 被减为了 0,于是向最初发出数据包的计算机发送一个 ICMP TTL 数据包,Traceroute 程序以此获得了与目标主机之间的路径上的第一个路由器的IP地址。后面 traceroute 程序依次向目标主机发送 TTL 为 2、3、4 . . . 的数据包,逐个探测出来与目标主机之间的路径上每一个路由器的 IP 地址。
实现
默认条件下,traceroute 首先发出 TTL = 1 的UDP 数据包,第一个路由器将 TTL 减 1 得 0 后就不再继续转发此数据包,而是返回一个 ICMP 超时报文,traceroute 从超时报文中即可提取出数据包所经过的第一个网关的 IP 地址。然后又发送了一个 TTL = 2 的 UDP 数据包,由此可获得第二个网关的 IP 地址。依次递增 TTL 便获得了沿途所有网关的 IP 地址。
注意
并不是所有网关都会如实返回 ICMP 超时报文。处于安全性考虑,大多数防火墙以及启用了防火墙功能的路由器缺省配置为不返回各种 ICMP 报文,其余路由器或交换机也可能被管理员主动修改配置变为不返回 ICMP 报文。因此 Traceroute 程序不一定能拿到所有的沿途网关地址。所以,当某个 TTL 值的数据包得不到响应时,并不能停止这一追踪过程,程序仍然会把 TTL 递增而发出下一个数据包。这个过程将一直持续到数据包发送到目标主机,或者达到默认或用参数指定的追踪限制(maximum_hops)才结束追踪。
依据上述原理,利用了 UDP 数据包的 Traceroute 程序在数据包到达真正的目的主机时,就可能因为该主机没有提供 UDP 服务而简单将数据包抛弃,并不返回任何信息。为了解决这个问题,Traceroute 故意使用了一个大于 30000 的端口号,因 UDP 协议规定端口号必须小于 30000 ,所以目标主机收到数据包后唯一能做的事就是返回一个 “端口不可达” 的 ICMP 报文,于是主叫方就将端口不可达报文当作跟踪结束的标志。
第7章 Ping程序和traceroute程序的更多相关文章
- TCP/IP详解之:Ping程序、Traceroute程序
Ping程序: ping程序是通过发送一份ICMP回显请求报文(即ICMP报文的一种,其类型为8,代码为0)给主机,并等待返回ICMP回显应答 来测试另一台主机是否可达. ping程序不用经过传输层, ...
- TCP/IP详解 卷一(第七、八章 Ping、Traceroute程序)
Ping程序 Ping程序由Mike Muuss编写,目的是为了测试另一台主机是否可达. 该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答. ping程序还能测出到这台主机的往返时 ...
- TCP/IP详解,卷1:协议--第8章 Traceroute程序
引言 由Van Jacobson编写的Tr a c e r o u t e程序是一个能更深入探索T C P / I P协议的方便可用的工具. 尽管不能保证从源端发往目的端的两份连续的 I P数据报具有 ...
- 第六章第一个linux个程序:统计单词个数
第六章第一个linux个程序:统计单词个数 从本章就开始激动人心的时刻——实战,去慢慢揭开linux神秘的面纱.本章的实例是统计一片文章或者一段文字中的单词个数. 第 1 步:建立 Linu x 驱 ...
- 第一章 第一个spring boot程序(转载)
第一章 第一个spring boot程序 本编博客转发自:http://www.cnblogs.com/java-zhao/p/5324185.html 环境: jdk:1.8.0_73 mave ...
- Traceroute程序
Linux和Unix中为traceroute,Windows中对应的是Tracert.如:Tracert www.baidu.com 输出为路由信息. C:\Users\Administrator ...
- 敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述
第13章 写给C#程序员的UML概述 UML包含3类主要的图示.静态图(static diagram)描述了类.对象.数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构.动态图(dy ...
- “全栈2019”Java第九章:解释第一个程序
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Linux下ping命令、traceroute命令、tracert命令的使用
Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地址192.168.1.1试试”. ...
随机推荐
- 多态 Java 2015/9/16
多态:http://www.cnblogs.com/chenssy/p/3372798.html 多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定, ...
- c语言输出4*5的数列?
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 输出上面的数列,用c实现的代码:<pre lang="c" line=&quo ...
- 每天一个linux命令:【转载】more命令
more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会 ...
- (function($){...})(jQuery)与$(function(){...})区别
$(function(){...}) 这种写法和jQuery(function(){...}),$(document).ready(function(){...})作用一样,表示文档载入后需要运行的代 ...
- 20179223《Linux内核原理与分析》第七周学习笔记
视频知识学习 1.fork()函数被调用一次,但返回两次: 2.Linux通过复制父进程来创建一个子进程,通过调用fork来实现: 3.Linux会为每个子进程动态的分配一个task_struct结构 ...
- .NET Core/Framework 创建委托以大幅度提高反射调用的性能
都知道反射伤性能,但不得不反射的时候又怎么办呢?当真的被问题逼迫的时候还是能找到解决办法的. 为反射得到的方法创建一个委托,此后调用此委托将能够提高近乎直接调用方法本身的性能.(当然 Emit 也能够 ...
- Python学习-lambda表达式
lambda只是一个表达式,函数体比def简单很多.lambda的主体是一个表达式,而不是一个代码块.仅仅能在lambda表达式中封装有限的逻辑进去.lambda表达式是起到一个函数速写的作用.允许在 ...
- UVA11538 Chess Queen
题意 给一个\(n \times m\)的棋盘,输出有多少种方法放置两个互相攻击的皇后. \(n,m \leq 10^6\) 分析 参照刘汝佳的题解. 横.竖.斜三种情况互不相干,加法原理统计. 横竖 ...
- ballerina 学习六 xml && json
ballerina xml && json 参考使用 代码比较简单,使用起来还是比较方便的 xml 代码说明: import ballerina/io; function main ( ...
- cockpit 使用(集成docker && k8s 管理)
1. yum 安装 sudo yum install cockpit 2. 允许启动 sudo systemctl enable --now cockpit.socket 3. 可选的插件 cockp ...