您的位置:首页 > 理论基础 > 计算机网络

小白学网络之六_TCPIP协议之ICMP协议

2013-09-26 21:43 489 查看
宁静而致远,按照自己的计划来做,人无时不刻不在博弈,在博弈中找到平衡,人都应该喜欢博弈,这样才会有成功的机会,我喜欢挑战,这样的人生才是精彩的。不以物喜,不以己悲。加油,在合适的时候,要勇敢的飞向天空。

ICMP Internet控制报文协议

ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层的协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。

ICMP报文是在IP数据报内部被传输的。



ICMP报文的格式如图所示,所有报文的前4个字节都是一样的,但是剩下的其他字节都互不相同。

类型字段可以有15个不同的值,一描述特定类型的ICMP报文。某些ICMP报文还是用代码字段的值来进一步描述不同的条件。

检验和字段覆盖整个ICMP报文。使用的算法与我们在3.2节中介绍的IP首部检验和算法相同。ICMP的检验和是必需的。



ICMP报文的类型

不同类型由报文中的类型字段和代码字段来共同决定。图中的最后两列表明ICMP报文是一份查询报文还是一份差错报文。因为对ICMP差错报文有时需要做特殊处理,因此我们需要对它们进行区分哦。例如,在对ICMP差错报文进行响应时,永远不会生成另一份ICMP差错报文。

当发送一份ICMP差错报文时,报文始终包含IP的首部和产生ICMP差错报文的IP数据报的前8个字节。这样,接收ICMP差错报文的模块就会把它与某个特定的协议(根据IP数据包首部中的协议字段来判断)和用户进程(根据包含在IP数据包前8个字节中的TCP或UDP报文首部中的TCP或UDP端口号来判断)联系起来。



下面各种情况都不会导致产生ICMP差错报文:

1) ICMP差错报文

2) 目的地址是广播地址或多播地址的IP数据报。

3) 作为链路层广播的数据报。

4) 不是IP分片的第一片。

5) 源地址不是单个主机的数据报。这就是说,源地址不能为零地址,环回地址,广播地址和多播地址。

这些规则是为了防止过去允许ICMP差错报文对广播分组响应带来的广播风暴。

ICMP地址掩码请求和应答

ICMP地址掩码请求用于无盘系统在引导过程中获取自己的子网掩码。系统广播它的ICMP请求报文(这一过程与无盘系统在引导过程中用RARP获取IP地址是类似的)。无盘系统获取子网掩码的另一个方法是BOOTP协议。ICMP地址掩码请求和应答报文的格式如下。



ICMP报文中的标识符和序列号字段由发送端任意选择设定,这些值在应答中将返回。这样,发送端就可以把应答与请求进行匹配。

ICMP时间戳请求和应答

ICMP时间戳请求允许系统向另一个系统查询当前的时间。返回的建议值是自午夜开始计算的毫秒数,协议的统一时间按。这种ICMP报文的好处是它提供了毫秒级的分辨率,而利用其他方法从别的主机获取的时间,只能提供妙级的分辨率。由于返回时间是从午夜开始计算的,因此调用者必须通过其他的方法得到当时的日期,这是它的一个缺陷。



请求端填写发起时间戳,然后发送报文。应答系统收到请求报文时填写接收时间戳,在发送应答时填写发送时间戳。但是,实际上,大多数的实现把后面两个字段都设置成相同的值。(提供三个字段的原因是可以让发生方分别计算发送请求的时间和发送应答的时间)

ICMP端口不可达差错

最后我们来讨论ICMP查询报文,地址掩码和时间戳查询和应答。现在来分析一种ICMP差错报文,即端口不可达报文,它是ICMP目的不可到达报文中的一种,以此来ICMP差错报文中所附加的信息。

UDP的规则之一是,如果收到一份UDP数据报的目的端口与某个正在使用的进程不相符,那么UDP返回一个ICMP不可达报文。可以用TFTP来强制生成一个端口不可达报文。

对于TFTP服务器来说,UDP的公共端口号是69.但是大多数的TFTP客户程序允许用connect命令来指定一个不同的端口号。这里,我们就用它来指定8888端口。



connect命令首先指定要连接的主机名以及其端口号,接着用get命令来取文件。敲入get命令后,一份UDP数据报就发送到主机svr4上的8888端口。tcpdump命令引起的报文交换结果如图所示:



在UDP数据报送到svr4之前,要先发送一份ARP请求来确定它的硬件地址。接着返回ARP应答,然后才发送UDP数据报。(在tcpdump的输出中保留ARP请求和应达是为了提醒我们,这些报文交换可能在第一个IP数据报从一个主机发送到另一个主机之前是必需的。)

一个ICMP端口不可达差错是立刻返回的,但是,TFTP客户程序看上去似乎忽略了这个ICMP报文,而在5秒钟之后又发送了另一份UDP数据报。在客户程序放弃之前重发了三次。

注意:ICMP报文是在主机之间交换的,而不用目的端口号,而每个20字节的UDP数据报则是从一个特定端口(2924)发送到另一个特定端口(8888).

跟在每个UDP后面的数字20指的是UDP数据报中的数据长度。在这个例子中,20字节包括TFTP的2个字节的操作代码,9个字节以空字符结束的文件名temp.foo,以及9个字节以空字符结束的字符串netascii.

如果用-e选项运行同样的例子,我们可以看到每个返回的ICMP端口不可达报文的完整长度,这里的长度为70字节,各字段分配如图。



ICMP的一个规则是,ICMP差错报文必须包括生成该差错报文的数据报IP首部,还必须至少包括跟在该IP首部后面的前8个字节。在我们的例子中,跟在IP首部后面的前8个字节包含UPD的首部。

一个重要的事实是包含在UDP首部中的内容是源端口号和目的端口号。就是由于目的端口号(8888)来把差错报文与某个特定的用户进程相关联。

导致差错的数据报中的IP首部要被送会的原因是因为IP首部中包含了协议字段,使得ICMP可以知道如何解释后面的8个字节。如果我们来查看TCP首部,可以发现源端口和目的端口都包含在TCP首部的前8个字节中。

ICMP不可达报文的一般格式如图:





当ICMP报文返回时,为什么TFTP客户程序还要继续重发请求了,这是因为在网络编程中一个因素,即BSD系统不把从插口(socket)接收到的ICMP报文中的UDP数据通知用户进程,除非该进程已经发送了一个connnet命令给该插口,标准的BSD TFTP客户程序并不发送connect命令,因此它永远也不会收到ICMP差错报文的通知。

这里需要注意的是另一点是TFTP客户程序所采用的不太好的超时重传算法。它只是假定5秒是足够的,因此每隔5秒就重传一次,总共需要25秒钟的时间。

ICMP报文的4.4BSD处理

由于ICMP覆盖的范围很广,从致命差错到信息差错,因此即使在一个给定的系统实现中,对每个ICMP报文的处理都是不相同的,它显示的是4.4BSD系统对每个可能的ICMP报文的处理方法。



如果最后一列标明是内核,那么ICMP就由内核来处理。如果最后一列指明是用户进程,那么报文就被传送到所有在内核中登记的用户进程,以读取收到的ICMP报文。如果不存在这样的用户进程,那么报文就悄悄地被丢弃。(这些用户进程还会收到所有其他类型的ICMP报文的拷贝,虽然它们应该由内核来处理,当然用户进程只有在内核处理以后才能收到这些报文有一些报文完全被忽略。最后,如果最后一列标明的是引号内的一串字符,那么它就是对应的Unix差错。其中一些差错,如TCP对发送端关闭的处理等,我们将在以后的章节对他们进行处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: