TCP/IP协议族学习(四):由Ping程序分析ICMP、IP以及以太网协议

来源:互联网 发布:mac zip 临时文件 编辑:程序博客网 时间:2024/06/05 16:19

Ping程序介绍

“ping”这个名字源于声纳定位操作,Ping程序由Mike Muuss编写,目的是为了测试另一台主机是否到达。Ping程序发送一份ICMP回显请求报文(类型为8,代码为0)给目的主机,并等待目的主机返回ICMP回显应答报文(类型为0,代码为0)。

我们以ping csdn主机为例来分析Ping程序回显请求及应答过程中,对应的ICMP协议,IP协议,以太网协议的各层数据包。数据报抓取使用了windows下赫赫有名的Wireshark。

Ping程序执行结果

以下为执行命令”ping www.csdn.net“的输出结果


使用Wireshark抓取的发送和接受到的数据包如下,我们可以看出共有4次回显请求和应答,和上图ping程序执行结果吻合。
图的下方蓝色部分即为一次ICMP回显请求中最终传送的数据,左侧为数据的16进制显示,右侧为对应的ascii码显示,我们接下来就是要逐步分层解析该数据,来理解ICMP,IP以及以太网协议。
(***对于数据报中实际的MAC地址进行了处理替换***)



了解协议封装

在展开了解各层协议之前,我们首先了解下封装,当应用程序使用TCP/IP协议族传送数据时,数据先被送入协议栈中,然后通过每一层直到被当作一串比特流送入网络,其中每一层对收到的数据都要增加本层协议对应的首部信息。以Ping程序为例,Ping程序要发送报文回显请求给目的主机,该报文先被送至网络IP层,在网络IP层增加IP首部后,送至链路层,在链路层增加以太网协议帧头后以字节流形式传送至物理网络。

ICMP回显请求报文

首先我们来看一下Ping程序使用的ICMP报文,ICMP回显请求报文是ICMP报文的一种,其报文格式如下图所示:
  • ICMP报文类型由报文中的类型和代码字段共同决定。
  • 检验和字段覆盖整个ICMP报文。
  • 通用ICMP报文首部只有第一个32bit字,包括:类型,代码,校验和组成,其后即为数据 部分,根据不同的类型和代码有不同的内容。
  • 对于ICMP回显请求报文,除去通用的ICMP报文首部,其首部增加了标识符以及序号字段。


下图蓝色部分即为本次Ping程序执行时对应的ICMP回显请求报文时的数据信息。


参考ICMP回显请求报文格式,可以看出:
  • 类型字段为:ICMP报文回显请求类型为8,报文应答类型为0。
  • 代码字段为:对于ICMP回显请求和回显应答,代码都为0。
  • 检验和字段为:0x4c51(big endian),检验和计算方法下面最后讨论。
  • 标志符字段为:0x0100,也就是256,《TCP/IP详解 卷1》上说Unix系统在实现ping程序时是把ICMP报文中的标识符字段置成发送进程的ID号,这样即使在同一台主机上同时运行多个ping程序实例,ping程序也可以识别出返回的信息。本次是在windows下运行的ping程序,不确定代表什么。
  • 序列号字段为:0x000b也就是11,序列号从0开始,每发送一次新的回显请求就加1,因此可以根据返回的每个分组的序列号,来查看是否有分组丢失、失序或者重复。
  • 数据:数据部分共32字节,由右侧ascii显示可以看出为字符串”abcdefghijklmnopqrstuvwabcdefghi“。

IP数据报

我们知道ICMP协议虽然和IP协议同属于网络层,但ICMP协议也像运输层TCP,UDP一样使用IP协议进行传送数据。上述ICMP回显报文送至IP层后,会附加上IP首部信息形成IP数据报,然后向下传送至链路层。至此,数据部分组成为:IP首部(20字节)+IP数据(即ICMP报文:ICMP首部(8字节)+数据(32字节))=60字节。
我们先了解下IP数据报的格式
  • 协议版本号:IPv4:4, IPv6:6
  • 首部长度:首部占32bit字的数目,包括选项,最大值为15,即首部最长为60字节,包括IP固定首部20字节以及最大40字节的选项字段。
  • 服务类型(TOS):优先权字段,大多数TCP/IP实现不支持TOS特性。
  • 总长度字段是指包括IP数据报首部的整个IP数据报的长度,以字节为单位。
  • 标识字段:唯一标识主机发送的每一份数据报,通常每发送一份报文它的值就会加1,用于数据报分片和重组。
  • 3位标志和13位片偏移:3为标志:0,DF(don't fragment,不要分片),MF(more fragments,还有分片),也用于分片和重组。DF位还用于路径MTU发现。
  • TTL(time-to-live)生存时间字段:设置了数据报可以经过的最多路由器数,它指定了数据报的生产时间。TTL初始值由源主机设置(通常为32或64),每经过一个处理它的路由器就减1,减为0时该数据报被丢弃,并发送ICMP报文通知源主机。
  • 8位协议字段:用来识别是那个协议向IP传送数据。
  • 16位首部校验和:根据IP首部计算的校验和码,它不对首部后面的数据进行计算。ICMP、IGMP、UDP和TCP在它们各自的首部均含有同时覆盖首部和数据的校验和码。
  • 32位源IP地址和32位目的IP地址。
  • 选项:可变长的可选信息,很少用,以32bit为长度单位。

下图蓝色部分即为在上面所述ICMP回显请求报文的基础上增加的IP协议首部信息,ICMP回显请求报文包含在IP数据报的数据部分。


由上图我们可以看出:
  • 协议版本号为4,即使用的IP协议版本为IP4。
  • 首部长度为5,即IP首部由5个32bit的字组成,也就是20个字节。
  • 服务类型(TOS)为0。
  • 总长度为0x003c,即60字节,即包含20字节的IP数据报首部和40字节的ICMP回显请求报文。
  • 标识字段为0x7d22,唯一标识主机发送的每一份数据报。下一次ICMP回显请求该字段就变为了0x7d23,也就是说每发送一次IP数据报,该标志字段就加1。
  • 3位标志和13位片偏移为0。
  • TTL(time-to-live)生存时间字段设为了64。
  • 8位协议字段为1,即ICMP协议。
  • 16位首部校验和为0xc833,根据IP首部计算的校验和码,它不对首部后面的数据进行计算。ICMP、IGMP、UDP和TCP在它们各自的首部均含有同时覆盖首部和数据的校验和码。
  • 32位源IP地址和32位目的IP地址,即从本机172.26.182.35发送到csdn主机117.79.93.222。
  • 选项数据无。

以太网数据帧

上面附加了IP数据报接下来就被传送至链路层,在链路层附加以太网协议首部后,随即便通过以太网发送至目标主机。
在TCP协议族中,链路层主要有三个目的:
  • 为网络层IP模块发送和接受IP数据报。
  • 为ARP模块发送ARP请求和接受ARP应答。
  • 为RARP发送RARP请求和接受RARP应答。
TCP/IP支持多种不同的链路层协议,这取决于不同的组网方式,如以太网,令牌环网,FDDI(光线分布式数据接口),RS-232串行线路等。
我们本次测试用的是最常用的以太网,所以上面所形成的IP数据报最终是以太网协议发送出去的。

以太网协议封装格式
  • 目的地址和源地址(各6字节):48bit的硬件地址,即我们常说的计算机的MAC地址,比如:68:a5:fb:94:32:fb。
  • 帧类型(2字节):表示后面的数据类型,比如:0x0800:IP数据报;0x0806:ARP请求/应答;0x8035:RARP请求/应答。
  • 目的地址,源地址以及类型被称为以太网帧头,以太网帧的数据部分要求最少要有46字节,如数据小于46字节,要在尾部填充字节。

下图是在前面所讲的ICMP回显报文以及IP数据报的基础上,增加了以太网协议首部(蓝色部分),最终形成了以太网帧。



由上图我们可以看出以太网协议的帧首部信息如下:
  • 目的主机地址为:28:94:0f:5f:ba:bf
  • 源主机地址为:78:2b:cb:d2:68:a5
  • 帧类型为:0x0800,即为IP数据报
至此,Ping程序发出的ICMP回显请求报文封装完毕,形成以太网帧,以字节流的形式发送给本主机所在网络的路由器,最终经过路由器层层转发,传送给csdn主机。

有一点说明一下:在IP协议中我们使用的地址是IP地址,但在以太网中,使用的是MAC硬件地址,这是因为IP地址只是人为划分的协议地址,两台计算机之间的通信最终还是要靠硬件来完成,每一台计算机的网卡都有唯一的物理地址,也就是我们常说的MAC地址,计算机之前的通信最终就是要要转换为使用物理地址进行,这个转换由ARP(地址解析协议)自动完成,应用程序不用关心。
那么上述以太网协议首部的目的主机地址是否就为csdn主机的物理地址了呢?当然不是,csdn主机离我们不知道有多远呢,我们当然没办法直接和它相连把数据发送给它。这儿靠的是IP路由选择,如果目的主机是和我们同一网络的主机,我们可以和它进行直接数据传输,不然就会根据IP路由表,把数据发送给同一网络上的路由器,由它进行转发,此处的目的主机也就是该路由器的物理地址。

ICMP回显应答报文

ICMP回显应答报文和回显请求报文基本类似,不同处在于:
  • 对于ICMP报文协议,ICMP回显应答报文类型变为0。
  • 对于IP层协议首部,源IP地址和目的IP地址进行了互换。
  • 对于以太网协议首部,源目的硬件地址和目的硬件地址进行了互换。


检验和计算方法

最后我们看一下检验和的计算方法:
以上述ICMP回显请求报文为例,为了计算ICMP报文的检验和,先把检验和字段置为0,然后对ICMP报文中每个16bit进行二进制反码求和(整个ICMP报文看成由一串16bit的字组成),结果存在检验和字段中。
当收到一份ICMP数据报时,同样对首部中每个16bit进行二进制反码求和,由于接受方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生错误的话,接收方的计算结果应该全为1,否则即数据报错误。

参考书籍《TCP/IP详解 卷1》


原创粉丝点击