OSI协议栈基础

OSI模型分为七层

OSI把网络按照层次分为七层,由下到上分别为物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

OSI
应用层 OSI参考模型中最靠近用户的一层,为应用程序提供网络服务。
表示层 提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。
会话层 负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
传输层 提供面向连接或非面向连接的数据传递以及进行重传前的差错检测。
网络层 提供逻辑地址,供路由器确定路径。
数据链路层 将比特组合成字节,再将字节组合成帧,使用链路层地址(以太网使用MAC地址)来访问介质,并进行差错检测。
物理层 在设备之间传输比特流,规定了电平、速度和电缆针脚。

数据封装与解封装图解

数据封装过程
OSI协议栈基础

解封装过程
OSI协议栈基础

传输层:TCP &UDP协议基本描述

TCP与UDP对比

传输控制协议(TCP) 用户数据报协议(UDP)
面向连接 无连接
可靠传输 尽力而为的传输
支持流控及窗口机制 无流控及窗口机制
HTTP、FTP等 TFTP、DNS、DHCP等

TCP报文:
OSI协议栈基础
源端口(Source Port):16bit, 表示报文发送方的端口号

目的端口(Destination port): 16bit,表示报文接收方的端口号

***(SN):32bit,标识了TCP报文中第一个byte在对应方向的传输中对应的字节序号。当SYN出现,序列码实际上是初始序列码(ISN),而第一个数据字节是ISN+1,单位是byte。比如发送端发送的一个TCP包净荷(不包含TCP头)为12byte,SN为5,则发送端接着发送的下一个数据包的时候,SN应该设置为5+12=17。通过***,TCP接收端可以识别出重复接收到的TCP包,从而丢弃重复包,同时对于乱序数据包也可以依靠系列号进行重排序,进而对高层提供有序的数据流。另外SYN标志和FIN标志在逻辑上也占用一个byte,当SYN标志位有效的时候,该字段也称为ISN(initial sequence number)。

确认号(ACK):32bit,标识了报文发送端期望接收的字节序列。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码,注意是准备接收的包,比如当前接收端接收到一个净荷为12byte的数据包,SN为5,则发送端可能会回复一个确认收到的数据包,如果这个数据包之前的数据也都已经收到了,这个数据包中的ACK Number则设置为12+5=17,表示17byte之前的数据都已经收到了。在举一个例子,如果在这个数据包之前有个SN为3,净荷为2byte的数据包丢失,则在接收端接收到这个SN为5的乱序数据包的时候,协议要求接收端必须要回复一个ACK确认包,这个确认包中的Ack Number只能设置为3。

头长(Header Length):4bit,指示TCP头的长度,即数据从何处开始。最大为15,单位是32比特,即4个字节,与IP头中的长度定义相同。

保留(Reserved):4bit,这些位必须是0。为了将来定义新的用途所保留,其中RFC3540将Reserved字段中的最后一位定义为Nonce标志。

标志(Code Bits):8bit

CWR(Congestion Window Reduce):拥塞窗口减少标志被发送主机设置,用来表明它接收到了设置ECE标志的TCP包,发送端将通过降低发送窗口的大小来降低发送速率

ECE(ECN Echo):ECN响应标志被用来在TCP3次握手时表明一个TCP端是否具备ECN功能,并且表明接收到的TCP包的IP头部的ECN被设置为11。更多信息请参考RFC793。

URG(Urgent):表示紧急(The urgent pointer) 指针是否有效。

ACK(Acknowledgment):1表示这是一个确认的TCP包, 0则不是确认包。

PSH(Push):该标志置位时,一般是表示发送端缓存中已经没有待发送的数据,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。

RST(Reset):用于复位相应的TCP连接。通常在发生异常或者错误的时候会触发复位TCP连接。

SYN(Synchronize):表示同步序列编号(Synchronize Sequence Numbers)是否有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接发起端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。

FIN(Finish):带有该标志置位的数据包用来结束一个TCP会话,但对应端口仍处于开放状态,准备接收后续数据。当FIN标志有效的时候我们称呼这个包为FIN包。

窗口大小(Window Size):16bit,表示从Ack Number开始还能接收多少字节的数据量,即当前接收端的接收窗口还有多少剩余空间。用于TCP的流量控制。

校验和(Checksum):16bit。发送端基于数据内容计算一个数值,接收端要与发送端数值结果完全一样,才能证明数据的有效性。接收端checksum校验失败的时候会直接丢掉这个数据包。CheckSum是根据伪头+TCP头+TCP数据三部分进行计算的。

紧急指针(Urgent Pointer):16位,在URG标志设置了时才有效。与序号字段的值相加后表示最后一个紧急数据的下一字节的序号,可以说这个字段是紧急指针相对当前序号的偏移。

选项(Option):长度不定,但长度必须以是32bits的整数倍。常见的选项包括MSS、SACK、Timestamp等等,后续的内容会分别介绍相关选项。

UDP报文:
OSI协议栈基础
源端口号(Source Port):16bit,指明发送数据的进程。

目的端口号(Destination Port):16bit,指明目的主机接收数据的进程。

长度(Length):16bit,该字段值为报头和数据两部分的总字节数。

检验和(Checksum):16bit,UDP检验和作用于UDP报头和UDP数据的所有位。由发送端计算和存储,由接收端校验。

数据(data)

TCP的连接与断开

OSI协议栈基础
1、主机A发送一个标识了SYN的数据段,表示期望与服务器B建立连接,此数据段的***(seq)为0。(***不确定,与系统有关,最大为2的32次方,超过循环)

2、服务器B回复标识了SYN+ACK的数据段,此数据段的***(seq)为0,确认***为主机A的***加1(0+1),以此作为对主机A的SYN报文的确认。

3、主机A发送一个标识了ACK的数据段,此数据段的***(seq)为0+1,确认***为服务器A的***加1(0+1),以此作为对服务器B的SYN报文段的确认。

OSI协议栈基础
1、主机A想终止连接,于是发送一个标识了FIN,ACK的数据段,***为101,确认***为301。

2、服务器B回应一个标识了ACK的数据段,***为301,确认序号为101+1,作为对主机A的FIN报文的确认。

3、服务器B想终止连接,于是向主机A发送一个标识了FIN,ACK的数据段,***为301,确认***为101+1。

4、主机A回应一个标识了ACK的数据段,***为101+1,确认序号为301+1,作为对服务器B的FIN报文的确认。
以上四次交互便完成了两个方向连接的关闭。

滑动窗口机制:
OSI协议栈基础
滑动窗口机制工作原理可参考此连接:https://www.cnblogs.com/luoquan/p/4886345.html

网络层

IP报文头部
OSI协议栈基础
版本:4bit,IP协议的版本号,分为IPv4和IPv6协议。

首部长度IHL:4bit,IPv4的首部长度。

区分服务Type of service:8bit,用来获得更好的服务。只有在使用区分服务时,这个字段才起作用。

总长度:16bit,指首部和数据之和的长度。

标识Identification:16bit,IPv4软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。

标志Flags:3bit,目前只有两位有意义。最低位为1表示后面“还有分片”的数据报,为0表示这已经是最后一个数据片;中间一位为1表示“不能分片”,为0才允许分片。

片偏移:13bit,指出较长的分组在分片后,该片在原分组中的相对位置。

生存时间TTL(Time To Live):8bit,表示数据报在网络中的寿命,功能是“跳数限制”。

协议 Protocol:8bit,指出此数据报携带的数据是使用何种协议。

首部检验和Header Checksum:16bit,数据报每经过一个设备,设备都要重新计算一下首部检验和,若首部未发生变化,则此结果必为0,于是就保留这个数据报。这个字段只检验数据报的首部,但不包括数据部分。

源地址Source Address:32bit,报文发送方的IPv4地址。

目的地址:32bit,报文接收方的IPv4地址。

选项字段Options:0~40字节(长度可变),用来支持排错、测量以及安全等措施。在必要的时候插入值为0的填充字节。数据部分可变用来填充报文。

IP地址分类

OSI协议栈基础
其中全0的主机号码表示该IP地址就是网络的地址,用于网络路由,全1的主机号码表示广播地址,即对该网络上所有的主机进行广播,127作为A类地址保留用于本地回环测试本地连通性。255.255.255.255用于局域网广播地址。

私有地址范围:

私有IP
A 10.0.0.0~10.255.255.255
B 172.16.0.0~172.31.255.255
C 192.168.0.0~192.168.255.255

默认子网掩码:

A 255.0.0.0
B 255.255.0.0
C 255.255.255.0

ARP协议

通过目的IP地址而获取目的MAC地址的过程是由ARP(Address Resolution Protocol)协议来实现的。
一台网络设备要发送数据给另一太网络设备时,必须要知道对方的IP地址。但是,仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过数据链路进行发送,而数据帧必须要包含目的MAC地址,因此发送端还必须获取到目的MAC地址。每一个网络设备在数据封装前都需要获取下一跳的MAC地址。IP地址由网络层来提供,MAC地址通过ARP协议来获取。ARP协议是TCP/IP协议簇中的重要组成部分,ARP能够通过目的IP地址发现目标设备的MAC地址,从而实现数据链路层的可达性。

ARP数据包格式
OSI协议栈基础
网络设备通过ARP报文来发现目的MAC地址。ARP报文中包含以下字段:

  1. Hardware Type表示硬件地址类型,一般为以太网;
  2. Protocol Type表示三层协议地址类型,一般为IP;
  3. Hardware Length和Protocol Length为MAC地址和IP地址的长度,单位是字节;
  4. Operation Code指定了ARP报文的类型,包括ARP request和ARP reply;
  5. Source Hardware Address指的是发送ARP报文的设备MAC地址;
  6. Source Protocol Address指的是发送ARP报文的设备IP地址;
  7. Destination Hardware Address指的是接收者MAC地址,在ARP request报文中,该字段值为0;
  8. Destination Protocol Address指的是指接收者的IP地址。

ARP工作过程:
通过ARP协议,网络设备可以建立目标IP地址和MAC地址之间的映射。网络设备通过网络层获取到目的IP地址之后,还要判断目的MAC地址是否已知。

ARP缓存:
网络设备一般都有一个ARP缓存(ARP Cache),ARP缓存用来存放IP地址和MAC地址的关联信息。在发送数据前,设备会先查找ARP缓存表。如果缓存表中存在对方设备的MAC地址,则直接采用该MAC地址来封装帧,然后将帧发送出去。如果缓存表中不存在相应信息,则通过发送ARP request报文来获得它。学习到的IP地址和MAC地址的映射关系会被放入ARP缓存表中存放一段时间。在有效期内,设备可以直接从这个表中查找目的MAC地址来进行数据封装,而无需进行ARP查询。过了这段有效期,ARP表项会被自动删除。
如果目标设备位于其他网络,则源设备会在ARP缓存表中查找网关的MAC地址,然后将数据发送给网关,网关再把数据转发给目的设备。

ARP请求:
OSI协议栈基础
本例中,主机A的ARP缓存表中不存在主机C的MAC地址,所以主机A会发送ARP request来获取目的MAC地址。ARP request报文封装在以太帧里。帧头中的源MAC地址为发送端主机A的MAC地址。此时,由于主机A不知道主机C的MAC地址,所以目的MAC地址为广播地址FF-FF-FF-FF-FF-FF。ARP request报文中包含源IP地址、目的IP地址、源MAC地址、目的MAC地址,其中目的MAC地址的值为0。ARP Request报文会在整个网络上传播,该网络中所有主机包括网关都会接收到此ARP request报文。网关将会阻止该报文发送到其他网络上。

ARP响应:
OSI协议栈基础
所有的主机接收到该ARP Request报文后,会检查它的目的协议地址字段与自身的IP地址是否匹配。如果不匹配,则该主机将不会响应该ARP Request报文。如果匹配,则该主机会将ARP报文中的源MAC地址和源IP地址信息记录到自己的ARP缓存表中,然后通过ARP Reply报文进行响应。
OSI协议栈基础

ARP缓存:
OSI协议栈基础
主机A收到ARP Reply以后,会检查ARP报文中目的MAC地址是否与自己的MAC匹配。如果匹配,ARP报文中的源MAC地址和源IP地址会被记录到主机A的ARP缓存表中。ARP表项的老化超时时间缺省为1200秒。

ARP代理:
OSI协议栈基础
在上述例子的组网中,主机A需要与主机B通信时,目的IP地址与本机的IP地址位于不同网络,但是由于主机A未配置网关,所以它将会以广播形式发送ARP Request报文,请求主机B的MAC地址。但是,广播报文无法被路由器转发,所以主机B无法收到主机A的ARP请求报文,当然也就无法应答。
在路由器上启用代理ARP功能,就可以解决这个问题。启用代理ARP后,路由器收到这样的请求,会查找路由表,如果存在主机B的路由表项,路由器将会使用自己的G0/0/0接口的MAC地址来回应该ARP request。主机A收到ARP reply后,将以路由器的G0/0/0接口MAC地址作为目的MAC地址进行数据转发。

免费ARP:
OSI协议栈基础
主机被分配了IP地址或者IP地址发生变更后,必须立刻检测其所分配的IP地址在网络上是否是唯一的,以避免地址冲突。主机通过发送ARP request报文来进行地址冲突检测。
主机A将ARP Request广播报文中的目的IP地址字段设置为自己的IP地址,该网络中所有主机包括网关都会接收到此报文。当目的IP地址已经被某一个主机或网关使用时,该主机或网关就会回应ARP reply报文。通过这种方式,主机A就能探测到IP地址冲突了。