一、TCP/IP五层模型
-
物理层(Physical Layer):物理层是最底层,负责传输比特流(bitstream)以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流,例如通过电缆、光纤或无线传输等。
-
数据链路层(Data Link Layer):数据链路层位于物理层之上,负责在直接相连的节点之间传输数据帧(Frame)。它将比特流组织成帧,并提供数据的可靠传输、差错检测和纠正等功能。常见的协议包括以太网(Ethernet)和Wi-Fi。
-
网络层(Network Layer):网络层处理分组(Packet)的传输和路由,负责将数据从源主机传输到目标主机。它定义了逻辑地址(如IP地址)和路由选择算法,并通过Internet Protocol (IP) 进行数据的分组、定址和转发。
-
传输层(Transport Layer):传输层提供端到端的可靠数据传输服务,负责将数据从发送方传输到接收方的端口。它通过传输协议(如TCP和UDP)提供了连接管理、流量控制、差错检测和纠正等功能。
-
应用层(Application Layer):应用层是最高层,负责处理特定应用程序之间的通信。它包括各种应用协议,如HTTP、FTP、SMTP和DNS等,用于实现不同应用程序之间的数据交换和通信。
二、IP协议特点
IP协议属于网络层协议,所有的TCP, UDP, ICMP, IGMP数据都通过IP数据报传输。IP提供了一种不可靠,无连接的数据包交付服务。依赖其他层的协议进行差错控制。
不可靠: IP数据报不保证能成功的到达目的地,如果出现错误则选择丢弃该数据,然后发送ICMP消息报给信源端
无连接: IP不提供任何后续数据报的状态信息,每个数据报处理都是独立的。如果一个信源发送了连续的两个数据报,每个数据报选择独立的路由,两个数据可能不同时到达。IP通信双方都不长久地维持对方的任何信息。这样上层协议每次发送数据的时候,都必须明确指定对方的IP地址。
IP协议是TCP/IP协议族的动力,为上层协议提供无状态,无连接,不可靠的服务。
-
无状态:指的是IP通信双方不同步传输数据的状态信息,因此所有IP数据报的发送,传输和接收都是相互独立,没有上下文关系的。这种服务最大缺点就是无法处理重复,乱序的这些情况。乱序:是第n个数据报比第n+1个后到接收端;重复:是同一个数据报通过不同路径多次到达接收端。这些情况ip端无法进行检测,因为这些数据之间没有上下文关系。接收端的iP模块只要接受的完整的IP数据报就将它交给传输层,所以上层协议的角度看这些数据就可能是乱序的,重复的。对于面向连接的协议比如说TCP协议可以自己处理乱序和重复的问题,然后经过TCP协议处理的数据交给上层肯定是有序的,正确的。但无状态也是有优点的:简单,高效。我们不需要为保持通信的状态而分配一些内核资源,也不需要传输数据时携带状态信息。
-
无连接:IP通信双方都不长久地维持对方仍和信息。所以每次发送数据的时候都必须指定对方的IP地址。
-
不可靠:IP协议不能保证IP数据报准确的到达接收端,它只是尽可能的保证发送过去,很多时候可能导致IP数据报发送失败,比如某个中转路由器发现IP数据报在网络存活时间太长就将其丢弃,并返回一个ICMP错误信息给发送端,接收端发现IP数据报不正确也会将其丢弃同时返回一个ICMP错误信息。无论是什么情况,发送端的iP模块检测到错误不会进行重传只会告诉传输层,传输层的协议比如TCP会自己实现数据确认,超时重传达到可靠的目的。
三、IP报文格式
RFC
https://www.rfc-editor.org/rfc/rfc791.txt
https://www.rfc-editor.org/rfc/rfc1349
https://www.rfc-editor.org/rfc/rfc2474
https://www.rfc-editor.org/rfc/rfc3168
IPv4
- 4位版本号(Version):指定IP协议的版本(IPv4/IPv6),对于IPv4来说,就是4。
- 4位首部长度(IHL):表示IP报头的长度,以4字节为单位。最大能表示15,所以IP报头最长是60字节。
- 8位服务类型(Type of Service):这个这个字段已经经历过几次重定义,参考后面报文优先级讲解。
- 16位总长度 (Total Length):IP报文(IP报头+有效载荷)的总长度,以字节为单位,因此IP数据报的最大长度为65535字节。由于MTU的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP分片数据报的长度远远没有达到最大值。
- 16位标识 (Identification):唯一地标识主机发送的每个一数据报。其初始值由系统随机生成:每发送一个数据报,其值就加1。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值。
- 3位标志字段 (Flags):
- 第一位保留。表示暂时没有规定该字段的意义;
- 第二位(Don't Fragment,DF)表示"禁止分片"。如果设置了这个位,IP 模块将不对数据报进行分片。在这种情况下,如果IP数据报长度超过MTU的话,IP 模块将丢弃该数据报并返回一ICMP差错报文。
- 第三位(More Fragment, MF)表示"更多分片"。若报文没有进行分片,则该字段设置为0,若报文进行了分片,则除了最后一个分片报文设置为0以外,其余分片报文均设置为1。
- 13位片偏移 (Fragment Offset):分片相对于原始数据开始处的偏移,表示当前分片在原数据中的偏移位置,实际偏移的字节数是这个值×8得到的。因此分片的报文中除了最后一个报文,其他报文的长度必须是8的整数倍,否则报文就不连续了。
- 8位生存时间(Time To Live,TTL):是数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置(常见的值是64)。数据报在转发过程中每经过一个路由,该值就被路由器减1。当TTL值减为0时,路由器将丢弃数据报,并向源端发送-一个ICMP差错报文。TTL值可以防止数据报陷人路由循环。
- 8位协议(Protocol):表示上层协议的类型。/etc/protocols 文件定义了所有上层协议对应的protocol字段的数值。其中,ICMP是1, TCP是6,UDP是17。
- 16位首部检验和 (Header Checksum):由发送端填充,接收端对其使用CRC算法以检验IP数据报头部,不检验数据部分。
- 32位源IP地址(Source Address): 表示发送端对应的IP地址。
- 32位目的IP地址(Destination Address):表示发送端和接收端所对应的IP地址。一般情况下,这两个地址在整个数据报的传递过程中保持不变,而不论它中间经过多少个中转路由器。
- 选项字段 (Options):不定长,最多40字节,因为IP头部最长是60字节(其中还包含前面讨论的20字节的固定部分)。可用的IP选项包括如下几种:
- 记录路由(recordroute),告诉数据报途经的所有路由器都将自己的IP地址填人IP头部的选项部分,这样我们就可以跟踪数据报的传递路径。
- 时间戳(timestamp),告诉每个路由器都将数据报被转发的时间(或时间与IP地址对)填人IP头部的选项部分,这样就可以测量途经路由之间数据报传输的时间。
- 松散源路由选择(loose source routing),指定一个路由 器IP地址列表,数据报发送过程中必须经过其中所有的路由器。
- 严格源路由选择(strict source routing),和松散源路由选择类似,不过数据报只能经过被指定的路由器。
在IP协议中,IP协议是面向非连接的,所谓的非连接就是在数据的传递过程中,不需要检测网络是否连通,所以是不可靠的数据报协议。IP协议主要用于在主机之间的寻址和选择数据包路由。
首部校验和
计算方式如下:
在发送端的时候,将校验和全部设置为0,然后把数据报首段数据全部进行反码相加,得到的值为校验和,放入首部的校验和字段;然后在接收端的时候,将数据报首段数据和校验和一起全部反码相加,最后若是得到零,则保留,若不是零,则说明数据报在传输过程中发生了改变,则丢弃该数据报。
IP报头与载荷分离
当IP从底层获取到一个报文后,首先读取报文的前20个字节,并从中提取出4位的首部长度,此时便获得了IP报头的大小size。若size的值大于20字节,则需要继续从报文中读取size−20字节的数据,这部分数据就是IP报头中的选项字段。
读取完IP的基本报头和选项字段后,剩下的就是有效载荷了。 IP协议通过这种"定长报头+自描述字段"的方式进行报头和有效载荷的分离。
4位二进制的取值范围是0000 ~ 1111,因此IP报头的最大长度为15 × 4 = 60字节。基本报头的长度是20字节,所以选项字段的长度最多为40字节。若IP报头中不携带选项字段,那么IP报头长度就为20字节,此时报头中的4位首部长度字段所填的值就是20 ÷ 4 = 5,即0101。
IP报头中的4位首部长度与TCP报头中的4位首部长度都以4字节为单位进行描述的,也恰好是报文的宽度。
载荷交付
基于IP协议的传输层协议不止一种,因此当IP从底层获取到一个报文并对其进行解包后,IP需要知道应该将分离后得到的有效载荷交付给上层的哪一个协议。
在IP报头中有一个字段叫做8位协议,该字段表示的就是上层协议的类型,IP就是根据该字段判定应该将分离出来的有效载荷交付给上层的哪一个协议。
该字段是发送方的IP层从上层传输层获取到数据后填充的,比如是上层TCP交给IP层的数据,那么该数据在封装IP报头时的8位协议填充的就是TCP对应的编号
32位源IP和目的IP
IP报头中的32位源IP地址和32位目的IP地址,分别代表的就是该报文的发送端和接收端对应的IP地址
数据在网络传输过程中会遇到一个个的路由器,这些路由器会帮助网络当中的数据进行路由转发,使得网络中的数据慢慢趋近于目标主机。路由器在帮助数据进行路由转发时,会提取出该数据的IP报头中的目的IP地址,并以此作为数据路由转发的重要依据
当接收端收到了发送端发来的数据后,接收端可能也想要给发送端发送数据,因此发送端在发送数据时除了需要指明该数据的目的IP地址,还需要指明该数据的源IP地址,即发送端的IP地址。即便接收端收到数据后没有数据想要发送,但至少需要向发送端发送一个响应报文,表明发送端发送的数据已经被接收端可靠的收到了
8位生存时间
报文在网络传输过程中,可能因为某些原因导致报文无法到达目标主机。如报文在路由时出现了环路路由的情况,或者目标主机已经异常离线了,此时这个报文就成了一个废弃的游离报文
为了避免网络中出现大量的游离报文,于是在IP的报头中就出现了一个字段:8位生存时间(Time To Live,TTL)。8位生存时间代表的是报文到达目的地的最大报文跳数,每当报文经过一次路由,生存时间就会减一,当生存时间减为0时该报文就被自动丢弃,在网络中消散
四、IP报文优先级与TOS
IPv4报文中有三种承载QoS优先级标签的方式,分别为基于二层的CoS字段(IEEE802.1p)的优先级、基于IP层的IP优先级字段ToS优先级和基于IP层的DSCP(Differentiated Services Codepoint)字段优先级。
TOS在不同协议中进行过定义,分别为RFC791、RFC1122、RFC1349;RFC1349废除了之前两个RFC定义,现在大多数设备使用RFC1349。
在DiffServ模型网络中又对TOS重新进行了定义, 即DSCP域。
对于IPv4报文,基于IPv4包首部中的ToS域的前三位(即IP Precedence)或前6位(即DSCP域)来标记报文。使用IP优先级可以将报文最多分成2^3=8类;使用DSCP域可将报文最多分成2^6=64类。
在实施Qos策略时,Cos与Tos或DSCP之间通常要做映射机制。
IEEE802.1p优先级
以太帧中可以插入IEEE 802.1Q选项来确定它属于哪个VLAN以及他的IEEE 802.1p优先级(QoS)
+-----------+----------+--------+-----------+
| TPID | PRI | CFI | VID |
| 2 Bytes | 3 Bits | 1 Bits | 12 Bits |
+-----------+----------+--------+-----------+
| |
| |
| |
| |
+-----------+-----------+--------------+---------------+------+-----------+----------+
| DMAC | SMAC | 802.1Q Tag | Length/Type | Data | FCS |
| 6 Bytes | 6 Bytes | 4 Bytes | 2 Bytes | Variable length | 4 Bytes |
+-----------+-----------+--------------+---------------+------+-----------+----------+
PRI(Priority)表示帧的QoS优先级,取值范围为0~7,值越大优先级越高,该优先级主要为QoS差分服务提供参考依据。当阻塞时,优先发送优先级高的数据包。
如果设置用户优先级,但是没有VID(VLAN ID),则VLAN ID必须设置为0x000。
RFC1349 TOS
https://www.rfc-editor.org/rfc/rfc1349 定义
RFC
0 1 2 3 4 5 6 7
+-----+-----+-----+-----+-----+-----+-----+-----+
| | | |
| PRECEDENCE | TOS | MBZ |
| | | |
+-----+-----+-----+-----+-----+-----+-----+-----+
优先级
比特0~2表示Precedence字段。代表报文传输的8个优先级,按照优先级从高到低顺序取值为7、6、......、1和0。最高优先级是7或6,经常是为路由选择或更新网络控制通信保留的,用户级应用仅能使用0~5级。
111 - Network Control (网络控制)
110 - Internetwork Control (网间控制)
101 - CRITIC/ECP (关键)
100 - Flash Override (疾速)
011 - Flash (闪速)
010 - Immediate (立即)
001 - Priority (优先)
000 - Routine (普通)
优先级6和7一般保留给网络控制数据使用,比如路由。
优先级5推荐给语音数据使用。
优先级4由视频会议和视频流使用。
优先级3给语音控制数据使用。
优先级1和2给数据业务使用。
优先级0为缺省标记值。
TOS
IP首部中的ToS字段,只能表示一种服务类别,也就是------这4bit字段中,最多只能有一个bit字段为1。
这四个字段组合在一起,表示了该数据报对应的服务类别,这个应用层的服务类别是不同的。这里所说的服务类别. 、
1000 -- minimize delay #最小延迟
0100 -- maximize throughput #最大吞吐量
0010 -- maximize reliability #最高可靠性
0001 -- minimize monetary cost #最小费用
0000 -- normal service #一般服务
最小延迟,对应于对延迟敏感的应用,如telnet和人login等。
最大吞吐量,对应于对吞吐量要求比较高的应用,如FTP文件应用,对文件传输吞吐量有比较高的要求。
最高可靠性,对网络传输可靠性要求高的应用,如使用SNMP的应用、路由协议等等。
最小费用,如NNTP这种用户网络新闻等。
ToS字段的服务类型未能在现有的IP网络中普及使用。
MBZ必须置0
RFC2474 DSCP
目前存在多种IP QoS服务模型,其中应用最广的是差分服务模型(DiffServ)。DiffServ模型的一个重要概念是在转发分组时体现服务等级的每跳行为PHB(Per Hop Behaviors)。DiffServ模型中,IETF重新定义了IPv4中的ToS和IPv6中的TC,称作DS字段,DS字段的取值称为DSCP(DiffServ code point)。不同的DSCP取值对应于不同的PHB。
DiffServ模型网络中实际部署的时候这8个优先级是远远不够的,于是RFC2474又对TOS重新进行了定义,把前六位定义为DSCP差分服务代码(Differentiated Services Code Point),后两位保留。
RFC3168中将TOS最后两位定义为ECN字段,用来控制拥塞比如用在RoCEv2环境。
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| DSCP | CU |
+---+---+---+---+---+---+---+---+
DSCP: differentiated services codepoint
CU: currently unused
在IPv4报文中,DS(Differentiated Service)字节的低6位(比特0~5)用作区分服务代码点DSCP。DSCP中的低3位(比特0~2)是类选择代码点CSCP(Class Selector Code Point),它表示了一类DSCP。网络中支持DiffServ技术的各设备根据DSCP值选择相应的转发行为。
在IPv6报文中,有两个字段与QoS有关,分别为流量类别TC(Traffic Class)和流标签FL(Flow Label)字段。流量类别字段有8位,和IPv4的服务类型(ToS)字段功能相同,用于对报文的业务类别进行标识;流标签字段有20位,用于标识属于同一业务流的包。流标签和源、目的地址一起,唯一标识了一个业务流。同一个流中的所有包具有相同的流标签,以便对有同样QoS要求的流进行快速、相同的处理。
PHB
在每一个DS节点上对分组的处理称为每跳行为PHB(Per-Hop Behavior)。PHB描述了DS节点对具有相同DSCP的分组采用的外部可见的转发行为。可以用优先级来定义PHB,也可以用一些可见的服务特征如分组延迟、抖动或丢包率来定义。PHB只定义了一些外部可见的转发行为,没有指定特定的实现方式。
标准协议定义了四种标准的PHB:类选择码CS(Class Selector),加速转发EF(Expedited Forwarding),确保转发AF(Assured Forwarding)和尽力而为BE(Best-Effort)。其中,BE是缺省的PHB。
DSCP取值与PHB
相关标准则定义比特0~5表示DSCP域,其中前3比特是类选择代码点CSCP(Class Selector Code Point),它表示了一类DSCP。DSCP优先级值有64个(0-63),0优先级最低,63优先级最高。事实上DSCP字段是IP优先级字段的超集,DSCP字段的定义向后与IP优先级字段兼容。网络中支持DiffServ技术的各设备根据DSCP值选择相应的PHB。
①、默认的DSCP为0
②、CS定义为向后与IP优先级兼容,后三位仍然为0,也就是说CS仍然沿用了IP PRECEDENCE只不过CS定义的DSCP=IP PRECEDENCE*8,所以CS1-7取值依次为8,16,24,32,40,48,56
③、EF取值46(101110)
④、AF分为两部分,a部分和b部分:a部分为3 bit仍然可以和IP PRECEDENCE对应;b部分为2 bit表示丢弃性,01为低,10为中,11为高(00未用),可以应用于RED或者WRED。虽然a部分有3bit,可以将AF分为8类,但是目前只用到了1~4,即AF只有4个等级AF1-AF4,每个等级有三个丢弃优先级,取值为[(10,12,14),(18,20,22),(26,28,30),(34,36,38)]
五、IP分片
当IP数据报的长度超过帧的MtU时,它将被分片传输。分片可能发生在发送端,也可能发生在中转路由器上,而且可能在传输过程中被多次分片,但只有在最终的目标机器上,这些分片才会被内核中的IP模块重新组装。
IP头部中的如下三个字段给IP的分片和重组提供了足够的信息:数据报标识、标志和片偏移。一个IP数据报的每个分片都具有自己的IP头部:
- 相同的标识值。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值。
- 不同的标志。 除了最后一个分片外,其他分片都将设置MP标志。
- 不同的片偏移。 每个分片在数据包的偏移是应该不同的。片偏移是8的整数倍。
- 每个分片的IP头部的总长度字段将被设置为该分片的长度。
示例
我已经修改当前MTU为1300, 所以两个主机使用1300MTU进行通信。
使用UDP发送了3068字节数据。这个UDP数据在IP层将被分层3片发送。每个IP分片都包含自己的IP头部(20 字节), 且第一个和第二各IP分片的IP头部设置了MF标志,而第三个IP分片的IP头部则没有设置该标志,因为它已经是最后一个分片了。原始IP数据报中的UDP头部内容被完整地复制到了第一个IP分片中。第二个和第三个IP分片不包含UDP头部信息,因为IP模块重组该报文的时候只需要一份IUDP头部信息,重复传送这个信息没有任何益处。
分片示意图如下:
IPv4的默认参数中勾选了IP分片的重组装,影响我们的分析IP分片。需要去掉勾选。
分片1
分片1包含UDP首部,也只有分片1包含首部。片偏移0。长度1300。id 0xed6f。包含更多分片。
分片2
片偏移1280,长度1300,id 0xed6f。包含更多分片。
分片3
片偏移2560,长度536,id 0xed6f。没有更多分片。
六、IP组包
目标主机收到所有的分片后,需要对它们进行重新组装,以重建原始IP数据包。这个过程称为组包。
- 接收到一个或多个数据段
- 每个数据段都会包标识值、标志、片偏移、总长度。
- 根据标识值、标志、片偏移、总长度,将所有数据段重新组合成一个完整的IP数据包
- 如果有数据段缺失或者损坏, 接收端会丢弃整个IP数据包。
参考:
https://blog.csdn.net/qq_15559817/article/details/104477897
https://blog.csdn.net/Rocketcp3/article/details/108874895
https://blog.csdn.net/legend050709/article/details/115470228
https://support.huawei.com/enterprise/zh/doc/EDOC1100334526/1c9211d
https://support.huawei.com/enterprise/zh/doc/EDOC1100334526/dd1b06d9