最后两小节我们来讨论ICMP查询报文—地址掩码和时间戳查询及应答。现在来分析一种ICMP差错报文,即端口不可达报文,它是ICMP目的不可到达报文中的一种,以此来看一看ICMP差错报文中所附加的信息。使用UDP(见第11章)来查看它。
UDP的规则之一是,如果收到一份UDP数据报而目的端口与某个正在使用的进程不相符,那么UDP返回一个ICMP不可达报文。可以用TFTP来强制生成一个端口不可达报文(TFTP将在第15章描述)。
对于TFTP服务器来说,UDP的公共端口号是69。但是大多数的TFTP客户程序允许用connect命令来指定一个不同的端口号。这里,我们就用它来指定8888端口:
![](https://box.kancloud.cn/2016-04-13_570de1e9e20c7.png)
connect命令首先指定要连接的主机名及其端口号,接着用get命令来取文件。敲入get命令后,一份UDP数据报就发送到主机svr4上的8888端口。tcpdump命令引起的报文交换结果如图6-8所示。
![](https://box.kancloud.cn/2016-04-13_570de1ea0eeac.png)
在UDP数据报送到svr4之前,要先发送一份ARP请求来确定它的硬件地址(第1行)。接着返回ARP应答(第2行),然后才发送UDP数据报(第3行)(在tcpdump的输出中保留ARP请求和应答是为了提醒我们,这些报文交换可能在第一个IP数据报从一个主机发送到另一个主机之前是必需的。在本书以后的章节中,如果这些报文与讨论的题目不相关,那么我们将省略它们)。
一个ICMP端口不可达差错是立刻返回的(第4行)。但是,TFTP客户程序看上去似乎忽略了这个ICMP报文,而在5秒钟之后又发送了另一份UDP数据报(第5行)。在客户程序放弃之前重发了三次。
注意,ICMP报文是在主机之间交换的,而不用目的端口号,而每个20字节的UDP数据报则是从一个特定端口(2924)发送到另一个特定端口(8888)。
跟在每个UDP后面的数字20指的是UDP数据报中的数据长度。在这个例子中, 20字节包括TFTP的2个字节的操作代码,9个字节以空字符结束的文件名temp.foo,以及9个字节以空字符结束的字符串netascii(TFTP报文的详细格式参见图15-1)。
如果用-e选项运行同样的例子,我们可以看到每个返回的ICMP端口不可达报文的完整长度。这里的长度为70字节,各字段分配如图6-9所示。
![](https://box.kancloud.cn/2016-04-13_570de1ea27618.png)
ICMP的一个规则是,ICMP差错报文(参见图6-3的最后一列)必须包括生成该差错报文的数据报IP首部(包含任何选项),还必须至少包括跟在该IP首部后面的前8个字节。在我们的例子中,跟在IP首部后面的前8个字节包含UDP的首部(见图11-2)。
一个重要的事实是包含在UDP首部中的内容是源端口号和目的端口号。就是由于目的端口号(8888)才导致产生了ICMP端口不可达的差错报文。接收ICMP的系统可以根据源端口号(2924)来把差错报文与某个特定的用户进程相关联(在本例中是TFTP客户程序)。
导致差错的数据报中的IP首部要被送回的原因是因为IP首部中包含了协议字段,使得ICMP可以知道如何解释后面的8个字节(在本例中是UDP首部)。如果我们来查看TCP首部(图17-2),可以发现源端口和目的端口被包含在TCP首部的前8个字节中。
ICMP不可达报文的一般格式如图6-10所示。
![](https://box.kancloud.cn/2016-04-13_570de1ea3e7c7.png)
在图6-3中,我们注意到有16种不同类型的ICMP不可达报文,代码分别从0到15。ICMP端口不可达差错代码是3。另外,尽管图6-10指出了在ICMP报文中的第二个32 bit字必须为0,但是当代码为4时(“需要分片但设置了不分片比特”),路径M T U发现机制(2.9节)却允许路由器把外出接口的MTU填在这个32 bit字的低16 bit中。我们在11.6节中给出了一个这种差错的例子。
尽管ICMP规则允许系统返回多于8个字节的产生差错的IP数据报中的数据,但是大多数从伯克利派生出来的系统只返回8个字节。Solaris 2.2的ip_icmp_return_data_bytes选项默认条件下返回前6 4个字节(E.4节)。
**tcpdump时间系列**
在本书的后面章节中,我们还要以时间系列的格式给出tcpdump命令的输出,如图6 - 11所示。
![](https://box.kancloud.cn/2016-04-13_570de1ea52cbc.png)
时间随着向下而递增,在图左边的时间标记与tcpdump命令的输出是相同的(见图6-8)。
位于图顶部的标记是通信双方的主机名和端口号。需要指出的是,随着页面向下的y坐标轴与真正的时间值不是成比例的。当出现一个有意义的时间段时,在本例中是每5秒之间的重发,我们就在时间系列的两侧作上标记。当UDP或TCP数据正在被传送时,我们用粗线的行来表示。
当ICMP报文返回时,为什么TFTP客户程序还要继续重发请求呢?这是由于网络编程中的一个因素,即BSD系统不把从插口(socket)接收到的ICMP报文中的UDP数据通知用户进程,除非该进程已经发送了一个connect命令给该插口。标准的BSD TFTP客户程序并不发送connect命令,因此它永远也不会收到I C M P差错报文的通知。
这里需要注意的另一点是TFTP客户程序所采用的不太好的超时重传算法。它只是假定5秒是足够的,因此每隔5秒就重传一次,总共需要25秒钟的时间。在后面我们将看到TCP有一个较好的超时重发算法。
TFTP客户程序所采用的超时重传算法已被RFC所禁用。不过,在作者所在子网上的三个系统以及Solaris 2.2仍然在使用它。AIX 3.2.2采用一种指数退避方法来设置超时值,分别在0、5、15和35秒时重发报文,这正是所推荐的方法。我们将在第21章更详细地讨论超时问题。
最后需要指出的是, ICMP报文是在发送UDP数据报3.5 ms后返回的,这与第7章我们所看到的P i n g应答的往返时间差不多。
- 第1章 概述
- 1.1 引言
- 1.2 分层
- 1.3 TCP/IP的分层
- 1.4 互联网的地址
- 1.5 域名系统
- 1.6 封装
- 1.7 分用
- 1.8 客户-服务器模型
- 1.9 端口号
- 1.10 标准化过程
- 1.11 RFC
- 1.12 标准的简单服务
- 1.13 互联网
- 1.14 实现
- 1.15 应用编程接口
- 1.16 测试网络
- 1.17 小结
- 第2章 链路层
- 2.1 引言
- 2.2 以太网和IEEE 802封装
- 2.3 尾部封装
- 2.4 SLIP:串行线路IP
- 2.5 压缩的SLIP
- 2.6 PPP:点对点协议
- 2.7 环回接口
- 2.8 最大传输单元MTU
- 2.9 路径MTU
- 2.10 串行线路吞吐量计算
- 2.11 小结
- 第3章 IP:网际协议
- 3.1 引言
- 3.2 IP首部
- 3.3 IP路由选择
- 3.4 子网寻址
- 3.5 子网掩码
- 3.6 特殊情况的IP地址
- 3.7 一个子网的例子
- 3.8 ifconfig命令
- 3.9 netstat命令
- 3.10 IP的未来
- 3.11 小结
- 第4章 ARP:地址解析协议
- 4.1 引言
- 4.2 一个例子
- 4.3 ARP高速缓存
- 4.4 ARP的分组格式
- 4.5 ARP举例
- 4.5.1 一般的例子
- 4.5.2 对不存在主机的ARP请求
- 4.5.3 ARP高速缓存超时设置
- 4.6 ARP代理
- 4.7 免费ARP
- 4.8 arp命令
- 4.9 小结
- 第5章 RARP:逆地址解析协议
- 5.1 引言
- 5.2 RARP的分组格式
- 5.3 RARP举例
- 5.4 RARP服务器的设计
- 5.4.1 作为用户进程的RARP服务器
- 5.4.2 每个网络有多个RARP服务器
- 5.5 小结
- 第6章 ICMP:Internet控制报文协议
- 6.1 引言
- 6.2 ICMP报文的类型
- 6.3 ICMP地址掩码请求与应答
- 6.4 ICMP时间戳请求与应答
- 6.4.1 举例
- 6.4.2 另一种方法
- 6.5 ICMP端口不可达差错
- 6.6 ICMP报文的4.4BSD处理
- 6.7 小结
- 第7章 Ping程序
- 7.1 引言
- 7.2 Ping程序
- 7.2.1 LAN输出
- 7.2.2 WAN输出
- 7.2.3 线路SLIP链接
- 7.2.4 拨号SLIP链路
- 7.3 IP记录路由选项
- 7.3.1 通常的例子
- 7.3.2 异常的输出
- 7.4 IP时间戳选项
- 7.5 小结
- 第8章 Traceroute程序
- 8.1 引言
- 8.2 Traceroute程序的操作
- 8.3 局域网输出
- 8.4 广域网输出
- 8.5 IP源站选路选项
- 8.5.1 宽松的源站选路的traceroute程序示例
- 8.5.2 严格的源站选路的traceroute程序示例
- 8.5.3 宽松的源站选路traceroute程序的往返路由
- 8.6 小结
- 第9章 IP选路
- 9.1 引言
- 9.2 选路的原理
- 9.2.1 简单路由表
- 9.2.2 初始化路由表
- 9.2.3 较复杂的路由表
- 9.2.4 没有到达目的地的路由
- 9.3 ICMP主机与网络不可达差错
- 9.4 转发或不转发
- 9.5 ICMP重定向差错
- 9.5.1 一个例子
- 9.5.2 更多的细节
- 9.6 ICMP路由器发现报文
- 9.6.1 路由器操作
- 9.6.2 主机操作
- 9.6.3 实现
- 9.7 小结