OSI七层模型中的报文封装详解

一 、OSI七层模型

上三层(会话/表示/应用):HTTP/FTP协议等——数据
传输层:     TCP协议/UDP协议——数据  TCP/IP(HEAD) 段
网络层:     IP/ICMP/ARP/RARP协议——数据  TCP/IP(HEAD) IP(HEAD) 包
数据链路层:ppp点到点—— 数据  TCP/IP(HEAD) IP(HEAD) 帧
物理层:     111111111111000000000000000011  比特

个人总结:记住各层主要协议,了解每层全部协议可以单独google.

二、基础概念整理

1.报文(message)是网络中交换与传输的数据单元,即站点一次性要发送的数据块。报文包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变。

2.OSI七层模型中,数据从上层应用到物理层一层一层封装:上三层的数据流在传输层被封装成数据段,在网络层数据段被封装成数据包,在数据链路层数据包被封装成数据帧,在物理层数据帧被封装成比特流。解封装则反之。

三、报文封装详解

传输层TCP报文段的封装:

TCP 报文段的报头有 10 个必需的字段和 1 个可选字段。报头至少为 20 字节。报头后面的数据是可选项。

1)源端口(16位)
标识发送报文的计算机端口或进程。一个 TCP 报文段必须包括源端口号,使目的主机知道应该向何处发送确认报文。
2)目的端口(16位)
标识接收报文的目的主机的端口或进程。
3) 序号(也叫序列号)(32位)
用于标识每个报文段,使目的主机可确认已收到指定报文段中的数据。当源主机用于多个报文段发送一个报文时,即使这些报文到达目的主机的顺序不一样,序列号也可以使目的主机按顺序排列它们。

在 SYN 标志未置位时,该字段指示了用户数据区中第一个字节的序号;在 SYN 标志置位时,该字段指示的是初始发送的序列号。

在建立连接时发送的第一个报文段中,双方都提供一个初始序列号。TCP 标准推荐使用以 4ms 间隔递增 1 的计数器值作为这个初始序列号的值。使用计数器可以防止连接关闭再重新连接时出现相同的序列号。

对于那些包含数据的报文段,报文段中第一个数据字节的数量就是初始序列号,其后数据字节按顺序编号。如果源主机使用同样的连接发送另一个报文段,那么这个报文段的序列号等于前一个报文段的序列号与前一个报文段中数据字节的数量之和。例如,假设源主机发送 3 个报文段,每个报文段有 100 字节的数据,且第一个报文段的序列号是 1000,那么第二个报文段的序列号就是 1100(1000 + 100),第三个报文段的序列号就是 1200(1100 + 100)。

如果序列号增大至最大值将复位为 0。
4)确认号(32位)
目的主机返回确认号,使源主机知道某个或几个报文段已被接收。如果 ACK 控制位被设置为 1,则该字段有效。确认号等于顺序接收到的最后一个报文段的序号加 1,这也是目的主机希望下次接收的报文段的序号值。返回确认号后,计算机认为已接收到小于该确认号的所有数据。

例如,序列号等于前一个报文段的序列号与前一个报文段中数据字节的数量之和。例如,假设源主 机发送 3 个报文段,每个报文段有 100 字节的数据,且第一个报文段的序列号是 1000,那么接收到第一个报文段后,目的主机返回含确认号1100 的报头。接收到第二个报文段(其序号为 1100 )后,目的主机返回确认号 1200。接收到第三个报文段后,目的主机返回确认号 1300 。

目的主机不一定在每次接收到报文段后都返回确认号。在上面的例子中,目的主机可能等到所有 3 个报文段都收到后,再返回一个含确认号 1300 的报文段,表示已接收到全部 1200 字节的数据。但是如果目的主机再发回确认号之前等待时间过长,源主机会认为数据没有到达目的主机,并自动重发。
上面的例子中,如果目的主机接收到了报文段号为 1000 的第一个报文段以及报文段号为 1200 的最后一个报文段,则可返回确认号 1100,但是再返回确认号 1300 之前,应该等待报文段号为 1100 的中间报文段。
5) 数据偏移(首部长度)(4位)
TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,即首部长度。 由于 TCP 报头的长度随 TCP 选项字段内容的不同而变化,因此报头中包含一个指定报头字段的字段。该字段以 32 比特为单位,所以报头长度一定是 32 比特的整数倍,有时需要在报头末尾补 0 。如果报头没有 TCP 选项字段,则报头长度值为 5 ,表示报头一个有 160 比特,即 20 字节。
6)保留位(6位)
由跟在数据偏移字段后的 6 位构成, 全部为 0 。
7)控制位(6位)
紧急 URG:此位置 1,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送。

确认 ACK:仅当 ACK = 1 时确认号字段才有效,TCP 规定,在连接建立后所有传达的报文段都必须把 ACK 置 1。

推送 PSH: 当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP 就可以使用推送(push)操作,这时,发送方 TCP 把 PSH 置 1 ,并立即创建一个报文段发送出去,接收方收到 PSH = 1 的报文段,就尽快地(即“推送”向前)交付给接收应用进程,而不再等到整个缓存都填满后再向上交付。

复位 RST:用于复位相应的 TCP 连接

同步 SYN:仅在三次握手建立 TCP 连接时有效。当 SYN = 1 而 ACK = 0 时,表明这是一个连接请求报文段,对方若同意建立连接,则应在相应的报文段中使用 SYN = 1 和 ACK = 1。因此,SYN 置 1 就表示这是一个连接请求或连接接受报文。

终止 FIN:用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
8)窗口(16位)
此字段用来进行流量控制,这个值是本机期望一次接收的字节数,即发送数据的窗口大小。告诉对方在不等待确认的情况下,可以发来多大的数据。这里表示的最大长度是2^16 – 1 = 65535,如需要使用更大的窗口大小,需要使用选项中的窗口扩大因子选项。

指发送本报文段的一方的接收窗口(而不是自己的发送窗口)。
9)校验和(16位)
源主机和目的主机根据 TCP 报文段以及伪报头的内容计算校验和。在伪报头中存放着来自 IP 报头以及 TCP 报文段长度信息。与 UDP 一样,伪报头并不在网络中传输,并且在校验和中包含伪报头的目的是为了防止目的主机错误地接收存在路由的错误数据报。

伪首部, 又称为伪包头(Pseudo Header):是指在 TCP 的分段或 UDP 的数据报格式中,在数据报首部前面增加源 IP 地址、目的 IP 地址、IP 分组的协议字段、TCP 或 UDP 数据报的总长度等共12字节,所构成的扩展首部结构。此伪首部是一个临时的结构,它既不向上也不向下传递,仅仅只是为了保证可以校验套接字的正确性。
10)紧急指针(16位)
仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据),即指出了紧急数据的末尾在报文中的位置,注意:即使窗口为零时也可发送紧急数据。

如果 URG 为 1 ,则紧急指针标志着紧急数据的结束。其值是紧急数据最后 1 字节的序号,表示报文段序号的偏移量。例如,如果报文段的序号是 1000,前 8 个字节都是紧急数据,那么紧急指针就是 8 。紧急指针一般用途是使用户可中止进程。
11)选项、填充字段
可能包括“窗口扩大因子”、“时间戳”等选项。长度可变,最长可达 40 字节,当没有使用选项时,TCP 首部长度是 20 字节。

填充用于保证任选项为 32bit 的整数倍。
12)数据(长度可变)
TCP 首部结束之后的部分

传输层UDP报文段的封装:

UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

1)源端口(2 字节):发送方端口号

2)目的端口(2 字节 ):接收方端口号

3)报文长度(2 字节):UDP 用户数据报的总长度,以字节为单位。

4)校验和(2 字节):检测 UDP 用户数据报在传输中是否有错,有错就丢弃。

用于校验 UDP 数据报的数字段和包含 UDP 数据报首部的“伪首部”。

伪首部, 又称为伪包头(Pseudo Header):是指在 TCP 的分段或 UDP 的数据报格式中,在数据报首部前面增加源 IP 地址、目的 IP 地址、IP 分组的协议字段、TCP 或 UDP 数据报的总长度等共12字节,所构成的扩展首部结构。此伪首部是一个临时的结构,它既不向上也不向下传递,仅仅只是为了保证可以校验套接字的正确性。

5)数据:UDP 的数据部分如果不为偶数需要用 0 填补,就是说,如果数据长度为奇数,数据长度加“1”。

网络层IP报文包的封装

IP数据报首部的固定部分中的各字段

版本:占4位,指IP协议的版本.通信双方使用的IP协议版本必须一致.日前广泛使用的 IP协议版本号为 4 (即 IPv4).IPv6 目前还处于起步阶段.
首部长度:占 4 位,可表示的最大十进制数值是15.请注意,这个字段所表示数的单位是32位字 (1个32位字长是4 字节),因此,当 IP 的首部长度为 1111 时 (即十进制的 15),首部长度就达到 60字节.当 IP 分组的首部长度不是4字节的整数倍时,必须利用最后的填充字段加以填充.因此数据部分永远在 4字节的整数倍开始,这样在实现 IP协议时较为方便.首部长度限制为 60字节的缺点是有时可能不够用.这样做的目的是希望用户尽量减少开销.最常用的首部长度就是 20 字节 (即首部长度为 0101),这时不使用任何选项.
服务:占 8 位,用来获得更好的服务.这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过.1998年IETF把这个字段改名为区分服务 DS(Differentiated Services).只有在使用区分服务时,这个字段才起作用.
总长度:总长度指首都及数据之和的长度,单位为字节.因为总长度字段为 16位,所以数据报的最大长度为 216-1=65 535字节.在IP层下面的每一种数据链路层都有自己的帧格式,其中包括帧格式中的数据字段的最大长度,即最大传送单元 MTU (Maximum Transfer Unit).当一个数据报封装成链路层的帧时,此数据报的总长度 (即首部加上数据部分)一定不能超过下面的数据链路层的MTU值,否则要分片.
标识 (Identification):占 16位.IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加 1,并将此值赋给标识字段.但这个”标识”并不是序号,因为 IP是无连接的服务,数据报不存在按序接收的问题.当数据报由于长度超过网络的 MTU 而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中.相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报.
标志 (Flag):占3 位,但目前只有2位有意义. 标志字段中的最低位记为 MF(More Fragment).MF=1即表示后面”还有分片”的数据报.MF=0表示这已是若干数据报片中的最后一个.标志字段中间的一位记为DF(Don’t Fragment),意思是”不能分片”,只有当 DF=0时才允许分片.
片偏移:占 13位.较长的分组在分片后,某片在原分组中的相对位置.也就是说,相对用户数据字段的起点,该片从何处开始.片偏移以 8个字节为偏移单位,这就是说,每个分片的长度一定是 8字节(64位)的整数倍.
生存时间:占 8位,生存时间字段常用的英文缩写是TTL(Time To Live),其表明数据报在网络中的寿命.由发出数据报的源点设置这个字段.其目的是防止无法交付的数据报无限制地在因特网中兜圈子,因而白白消耗网络资源.最初的设计是以秒作为 TTL的单位.每经过一个路由器时,就把TTL减去数据报在路由器消耗掉的一段时间.若数据报在路由器消耗的时间小于 1 秒,就把TTL值减 1.当 TTL值为 0时,就丢弃这个数据报.
协议:占 8 位.协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程.详细资料请看文章最后的注释.
首部检验和:占 16位.这个字段只检验数据报的首部,但不包括数据部分.这是因为数据报每经过一个路由器,都要重新计算一下首都检验和 (一些字段,如生存时间,标志,片偏移等都可能发生变化),不检验数据部分可减少计算的工作量.
源地址:占32位.
目的地址:占 32位.

实例

下面是一个TCP的SYN数据包,大家可以分析一下:

4500002C2A690000-4006B7580A616750-7CACAAAD24DE0E89-12DE958000000000-60023908EA4D0000-020405B4

  • 版本:4,即IPv4;
  • 首部长度:5,即5*8=20B,说明没有可变部分;
  • 服务:00;
  • 总长度:002C,44B;
  • 标识:2A69;
  • 标志+片偏移:0000;
  • 生存时间:40,即64;
  • 协议:06,传输控制协议,也就是TCP;
  • 首部校验和:B758;
  • 源地址:0A616750;
  • 目的地址:7CACAAAD.

后面的数据时TCP的头部,这里先简单列出来,后面会详细分析:

  • 源端口:24DE;
  • 目的端口:0E89;
  • 序号:12DE9580;
  • 确认号:00000000;
  • 数据偏移:6,即偏移24B.TCP的头部默认是20B,我们分析的数据包有一个TCP选项,占4B;
  • 保留+控制位:002,表明这是一个SYN包;
  • 窗口值:3908,14600,即发送者的接收窗口值;
  • 校验和:EA4D;
  • 紧急指针:0000;
  • 选项类型:02,最大报文段长度;
  • 选项长度:04;
  • 选项数据:05B4,即1355.

数据链路层中数据帧的封装:

网络层协议的数据单元是 IP 数据报 ,而数据链路层的工作就是把网络层交下来的 IP 数据报封装为帧(frame)发送到链路上,以及把接收到的帧中的数据取出并上交给网络层。 为达到这一目的,数据链路必须具备一系列相应的功能,主要有:

  • 将数据封装为帧(frame),帧是数据链路层的传送单位;
  • 控制帧的传输,包括处理传输差错,调节发送速率与接收方相匹配;
  • 在两个网络实体之间提供数据链路通路的建立、维持和释放的管理。

数据帧的结构是这样的

以太网(Ether-net)是指 DEC 公司、Intel 公司和 Xerox 公司在 1982 年联合公布的一个标准,这个标准里面使用了一种称作 CSMA/CD 的接入方法。而 IEEE802 提供的标准集 802.3(还有一部分定义到了 802.2 中)也提供了一个 CSMA/CD 的标准。

这两个标准稍有不同,因此链路层数据帧的的封装格式也有所不同(数据帧中的地址为 MAC 地址):

CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。

OSI七层模型中的报文封装详解》上有1条评论

发表评论

邮箱地址不会被公开。