再读斋

TCP/IP(二)IP协议

IP协议属于TCP/IP网络模型的第三层-网络层,它的主要作用是实现终端节点之间的通信。IP协议是网络层的一个重要协议,网络层中还有ARP协议(获取MAC地址)和ICMP协议(数据发送异常通知)。

数据链路层的作用在于实现同一中数据链路下的包传递,而网络层则可以实现跨越不同数据链的包传递。比如主机A通过WI-FI连接到路由器B,路由器B通过以太网连接到路由器C,而路由器C又通过WI-FI与主机D保持连接,这时主机A向D发送的数据包就依赖于网络层进行传输。

IP大致分为三大作用模块:IP寻址、路由以及IP分包和组包

IP地址

IP地址是一种在网络层用于识别通信对端信息的地址,它有别于数据链路层中的MAC地址,后者用于标识同一链路下不同的计算机。

IP地址由32为正整数表示,为了直观的表示,我们把它分成4个部分,每个部分由8位整数组成,对应十进制的范围就是0-255。比如172.20.1.1可以表示为:10101100 00010100 00000001 00000001.转换规则很简单,就是分别把四个部分的十进制(0-255)与8位二进制数进行转换。

从功能上看,IP地址由两部分组成:网络标识和主机标识。

  • 网络标识用于区分不同的网段,相同段内的主机必须拥有相同的网络标识,不同段内的主机不能拥有相同的网络标识。
  • 主机标识用于区分同一网段下不同的主机,它不能在同一网段内重复出现。

32为IP地址被分为两个部分,到底前多少为是网络标识呢?一般有两种方法表示:IP地址分类、子网掩码

IP分类

IP地址分为四个级别,分为A类、B类、C类和D类。分类的依据是IP地址的前四位。

  • A类地址

A类IP地址是第一位是0的地址。从第1位到第8位是A类IP地址的网络标识,用十进制标识的0.0.0.0~127.0.0.0是A类IP地址的理论范围。A类地址的后24位相当于主机标识。因此一个网段内可容纳的主机地址上线为2的24次方个。

  • B类地址

B类IP地址是前两位为“10”的地址。B类地址的前16位是网络标识,用十进制标识的话是128.0.0.0~191.255.0.0是B类地址的范围。B类地址的后16位是主机标识,因此一个网段可容纳主机地址上限为65534个。

  • C类地址

C类IP地址是前三位是“110”的地址。C类地址的前24位是网络标识,用十进制标识的话192.0.0.0~223.255.255.0是C类地址的范围。C类地址的后8位是主机标识,因此一个网段可容纳主机地址上限为254个。

  • D类地址

D类IP地址是前四位是“1110”的地址。D类地址的前32位是网络标识。用十进制表示的话224.0.0.0~239.255.255.255是D类地址的网络地址,D类地址没有主机标识,因此常用于多播。

  • 关于分配IP主句地址的注意事项

在分配IP地址时关于主机标识有一点需要注意,即要用比特位表示主机地址时,不可以全部为0或者全部为1.因为全部为0只有在表示对应的网络地址或IP地址不可或知的情况下才使用,而全部为1的主机地址通常作为广播地址。

因为在分配过程中,应该去掉这两种情况,这也是为什么C类地址每个网段最多只能有254(2^8 - 2)个主机地址的原因。

广播地址

广播地址用于在同一个链路中相互连接的主机之间发送数据的发送端IP地址中的主机地址部分全部设置为1,就是广播地址。例如把172.20.0.0用二进制表示如下:
10101100.00010100.00000000.00000000
将这个地址的主机部分全部改为1,形成广播地址:
10101100.00010100.11111111.11111111
再将这个地址用十进制表示,则为172.20.255.255

广播分为本地广播和直接广播

  • 本地广播

在本网络内的广播叫做本地广播。例如网络地址为192.168.0.4的情况下,广播地址是192.168.0.255.因为这个广播地址的IP包会被路由器屏蔽,所以不会到达192.168.0.4以外(如192.168.1.4)的其他链路上。

  • 直接广播

在不同网络之间的广播叫做直接广播。例如网络地址192.168.0.4的主机地址想192.168.1.255的目标地址发送IP包。收到这个包的路由器,将数据转发给192.168.1.0,从而使得所以192.168.1.1~192.168.1.254的主机都能收到这个包。

IP多播

多播用于将数据包发送给特定组内的所有主机。由于其直接使用IP协议,因此是不可靠的传输。

多播使用D类地址。因此,如果IP地址的前四位是“1110”,就可以认为是多播地址,而剩下的28位可以成为多播的组编号。

子网编码

一个IP地址有两种识别码:一是IP地址本身,而是表示网络部分的子网掩码。子网掩码用二进制表示的话也是一个32位的数字。它对应IP地址网络标识部分的位全部为“1”,对应IP地址主机标识的部分则全部为“0”。由此,一个IP地址可以不再受限于自己的类别,而是可以用这样的子网掩码自由地定位自己的网络标识长度。当然,子网掩码必须是IP地址的首位开始连续的“1”。

以IP地址172.20.100.52为例,它本来是一个B类IP地址(前16位是网络标识),但通过子网掩码,它可以扩展为前26位是网络标识的IP地址,其中定义类10位子网掩码,如图所示。

路由

路由控制表

发送数据包时所使用的地址是网络层的地址,即IP地址。然而仅仅有IP地址还不足以实现将数据包发送到对端目标地址,在数据发送过程中还需类似于“指明路由器或主机”的信息,以便真正发往目标地址。保存这种信息的就是路由控制表(Routing Table)。实现IP通信的主机和路由器都必须持有一张这样的表,它们也正是在这个表格的基础上才得以进行数据包发送的。

路由控制表的形成方式有两种:一种是管理员手动设置,另一种是路由器与其他路由器相互交换信息时自动刷新。前者也叫静态路由控制,而后者叫做动态路由控制。为了让动态路由及时刷新路由表,在网络上互连的路由器之间必须设置好路由协议,保证正常读取路由控制信息。

IP协议始终认为路由表是正确的。然而,IP本身并没有定义制作路由控制表的协议。即IP没有制作路由控制表的机制。该表是由一个叫做“路由协议”的协议制作而成。

路由控制

路由器中保存着路由控制表,它在路由控制表中查找目标IP地址对应的下一个路由器地址。

IP地址的网络地址部分用于进行路由控制,如下图所示

主机A的地址是10.1.1.30,要把数据发往地址为10.1.2.10的主机。在主机A的路由表中,保存了两个字段,由于目标地址10.1.2.10与10.1.1.0/24段不匹配,所以它被发往默认路由10.1.1.1也就是图中路由器1的IP地址。

路由器1继续在它自己的路由控制表中查找目标地址10.1.2.10,它发现目标地址属于10.1.2.0/24这一段,因此将数据转发至下一个路由器10.1.0.2,也就是路由器2的左侧网卡IP地址

路由器在自己的路由控制表中查找目标地址10.1.2.10,根据表中记录将数据发往10.1.2.1接口,也就是路由器右侧网卡的IP地址,主机B检查目标IP地址和自己相同,于是接收数据。

环路

上图中,假设主机A向一个不存在的IP地址发送数据,并且路由器1、2、3设置的默认路由形成了一个循环,那么数据将在网络中不断转发最终导致网络拥堵,这个问题将在下文分析IP首部时得到解决。

IP报文分割与重组

在数据链路层中,我们已经提到过不同的数据链路有不同的最大传输单元(MTU)。因此IP协议的一个任务是对数据进行分片和重组,分片由发送端主机和路由器负责,重组由接收端主机负责。

路径MTU发现

分片会加重路由器的负担,因此只要条件允许,我们都不希望路由器对IP数据包进行分片处理。另外,如果一个分片丢失,整个IP数据报都会作废。

解决以上问题的技术是“路径MTU发现”。主机首先获取整个路径中所有数据链路的最小MTU,并按照整个大小将数据分片。因此传输过程中的任何一个路由器都不用进行分片工作。

为了找到路径MTU,主机首先发送整个数据包,并将IP首部的禁止分片标志设为1.这样路由器在遇到需要分片才能处理的包时不会分片,而是直接丢弃数据并通过ICMP协议将整个不可达的消息发回主机。主机将ICMP通知中的MTU设置为当前MTU,根据真个MTU对数据进行分片处理。如此反复下去,直到不再收到ICMP通知,此时的MTU就是路径MTU。

以UDP协议发送数据为例:

重组

接收端根据IP首部中的标志(Flag)和片偏移(Fragment Offset)进行数据重组。

IP首部(IPv4)

IP首部是一个有些复杂的结构,我们不用记忆它的结构,只需了解每个部分的作用即可,这样可以加深对IP协议的理解。

  • 版本

由4比特构成,表示标识IP首部的版本号。IPv4的版本号即为4

  • 首部长度(IHL,Internet Header Length)

由4比特构成,表明IP首部的大小,单位为4字节。对于没有可选项的IP包,首部长度则设置为5.也就是说,当没有可选项时,IP首部的长度为20字节(4 * 5 = 20)

  • 区分服务(TOS:Type of Service)

由8比特组成,用来表明服务质量

DSCP(Differential Services Codepoint,差分服务代码点)是TOS的一部分,用来进行质量控制,由6个字节组成。
ECN(Explicit Congestion Nofication,显示拥塞通告),用来报告网络拥堵情况,由2bit构成。

  • 总长度

表示IP首部与数据部分结合起来的总字节数。该字段为16bit。因此IP包的最大长度为65535(2^16)个字节。虽然不同数据链路的MTU不同,但是IP协议屏蔽了这些区别,通过自己实现的数据分片功能,从上层的角度来看,IP协议总是能够以65535为最大包长进行传输。

  • 标识(ID)

由16比特组成,用于分片重组。同一分片的标识值相同,不同分片的标识值不同。通过每发送一个IP包,它的值也逐渐递增。此外即使ID相同,如果目标地址、源地址或协议不同的话,也会被认为是不同的分片。

  • 标志(Flags)

由3bit组成,表示包被分片的相关信息

  • 片偏移(FO,Fragment Offset)

由13bit构成,用来标识被分片的每一个分段相对于原始数据的位置。第一个分片对应的值为0.由于FO域占13位,因此最多可以表示8192(2^13)个相对位置。单位为8字节,因此最大可表示原始数据8 * 8192 = 65536字节的位置。

  • 生存时间(TTL:Time To Live)

由8比特构成,以秒为单位记录当前包在网络上应该生存的时间。在实际中它是指可以中转多少个路由器的意思。每经过一个路由器,TTL会减少1,直到变成0则丢弃该包。

  • 协议(Protocol)

由8bit构成,表示IP首部的下一个首部隶属于哪个协议。

  • 首部校验和(Header Checksum)

由16比特构成,也叫IP首部校验和。该字段只校验首部,不校验数据部分,主要用来确保IP数据包不被破坏。

  • 源地址(Source Address)

由32bit构成,表示发送端IP地址

  • 目标地址(Destination Address)

由32bit构成,表示接收端IP地址

  • 可选项(Options)

长度可变,通常只在进行实验或诊断时使用

  • 填充(Padding)

在有可选项的情况下,首部长度可能不是32bit的整数倍。为此,通过向字段填充0,调整32bit的整数倍。

  • 数据(Data)

存入数据。将IP协议的首部也作为数据进行处理。

刘涤生 wechat