第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试试”. ...
随机推荐
- ajax前置处理实现异步请求session过期时跳转登录页面
第一篇博文,mark一下zhq[0]. 问题描述:用户页面,当session过期或都session注销后,普通页面后端都会有过滤器,session过期Redirect到登录页面,但是ajax请求后端只 ...
- 文件的copy
def mycopy(src_filename, dst_filename): try: fr = open(src_filename, "rb") try: try: fw = ...
- Android编程实例-获取当前进程名字
下面代码是根据进程id获取进程名字: /** * 根据Pid获取当前进程的名字,一般就是当前app的包名 * * @param context 上下文 * @param pid 进程的id * @re ...
- stm32寄存器版学习笔记08 DMA
DMA(Direct Memory Access),直接存储器访问.DMA传输方式无需CPU直接控制传输,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,使CPU效率大大提高.stm32f10 ...
- BZOJ4903 UOJ300 CTSC2017 吉夫特 【Lucas定理】
BZOJ4903 UOJ300 CTSC2017 吉夫特 弱弱地放上题目链接 Lucas定理可以推一推,发现C(n,m)是奇数的条件是n" role="presentation&q ...
- Oracle中用exp/imp命令快速导入导出数据
from: http://blog.csdn.net/wangchunyu11155/article/details/53635602 [用 exp 数 据 导 出]: 1 将数据库TEST完全导出, ...
- 在线编辑器KindEditor的使用
1.官网下载:点击进入 2.解压后目录说明 ├── asp asp示例 ├── asp.net asp.net示例 ├── attached 空文件夹,放置关联文件attached ├── examp ...
- PF不明内存泄露已解决,白头发也没了(转)
在使用OpenExpressApp进行WPF应用开发过程中遇到多个内存泄漏的地方,在上一篇中求助了一个内存泄露问题[WPF不明内存泄露原因,头发都白了几根],本篇与大家分享一下如何解决此问题的过程. ...
- 使用PHP类库PHPqrCode生成二维码
PHPqrCode是一个PHP二维码生成类库,利用它可以轻松生成二维码,官网提供了下载和多个演示demo, 查看地址:http://phpqrcode.sourceforge.net/. 下载官 ...
- Linux下gdb线程的调试
多线程的调试命令 1.info threads: 这条命令显示的是当前可调试的所有线程,GDB会给每一个线程都分配一个ID.前面有*的线程是当前正在调试的线程. 2.thread ID: 切换到当前调 ...