1.IP协议
主机是配有IP地址,也要进行路由的设备。路由器是既有IP地址,又能进行路由的设备。主机和路由器右统称为节点。
1.1协议报头格式
IP协议的报头部分和TCP报头的大小是相同的(在都无选项的情况下),IP协议报头分为12部分(忽略选项),分别为:4位版本、4位首部长度、8位服务类型、16位总长度、16位标识、3位标志、13位片偏移量、8位生存时间、8位协议、16位首部检验和、32位源IP地址、32位目的地址。一共20字节,如果有选项的话就要另算。
首先4位版本号对应的是IP协议的版本,主流的有IPv4和IPv6,这两个版本互不兼容。4位首部长度跟TCP的4位首部长度一样,取值范围都是20到60字节。8位服务类型在现代网络中实际使用的是DSCP(区分服务码点)和ECN(显式拥塞通知),早期定义中的3位优先权字段已弃用,4位TOS字段(分别表示最小延时、最大吞吐量、最高可靠性、最小成本)也已不再使用,当时这四者互相冲突,只能选择一种。
16位总长度代表报文的总长度,最大值为65535字节。拿总长度减去报头长度就可以得到正文长度,从而解决数据粘包问题。16位标识用于分片时标识分包的数据报属于哪一个组,相同标识的数据报属于分片前的同一个数据报。那么数据报为什么要分片呢?其实是因为链路层规定了最大传输单元(MTU),常见以太网的MTU为1500字节,当IP报文超过这个大小时就需要分片了。3位标志位中,第一位是保留位,第二位为1表示禁止分包,第三位表示更多分片,也就是说如果最后一位为0表示是最后一个分片,其他分片该位为1。13位片偏移量表示该数据报在分片前的源数据报中的偏移量,因为偏移量只有13位,无法直接表示16位总长度范围内的所有位置,所以实际偏移量除以8后再存入该字段。也就是说,13位偏移量其实是实际偏移量除以8的结果,对端拿到偏移量后乘以8得到真正的偏移量。因此,除最后一个分片外,其他每个分片的数据部分长度都必须是8的整数倍。
8位生存时间是报文到达目的地允许经过的最大路由器跳数,初始值通常为64。每经过一个路由器减1,如果减到0仍未到达目的地,报文就会被丢弃,这主要是为了防止路由循环导致报文在网络中永远存在。8位协议标识上层协议,用于分用时确定该交给传输层的哪个协议(如TCP或UDP)。16位首部校验和采用Internet校验和(反码求和)进行校验,用于检测头部是否在传输过程中损坏。32位源IP地址和32位目的地址就是字面意思。
1.2网段划分
IP地址分为两个部分,网络号和主机号。网络号保证两个互相链接的网段具有不同的标识。主机号用于标识同一网段内的不同主机,相同子网的主机的网络号必须相同。曾经提出过一种划分网络号和主机号的方案,把所有IP地址分为五类,如下图。

A类从0.0.0.0到127.255.255.255,B类从128.0.0.0到191.255.255.255,C类从192.0.0.0到233.255.255.255,D类从244.0.0.0到239.255.255.255,E类从240.0.0.0到247.255.255.255。
但是因为使用互联网的人数越来越多,这种划分方案的局限性很快显现出来。大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而A类却浪费了大量地址。因为A类、B类这种一个子网理论上能允许很多主机,但实际一个子网里的主机数有限,远远达不到理论值,导致大量IP地址被浪费。为了解决以上问题,提出了新的划分方案,称为CIDR(无类别域间路由)。CIDR引入网络掩码来区分网络号和主机号。子网掩码是32位的整数,由**连续的1(网络部分)和连续的0(主机部分)**组成。将IP地址跟子网掩码按位与,得到的结果就是网络号。
在一个子网中,在子网掩码限定的主机位范围内,将主机地址全部设为0就成了网络号,代表这个局域网。将主机地址全部设为1就代表广播地址,用于向局域网内的所有主机发送信息。127.*的IP地址是用于本地环回的,通常是127.0.0.1。
我们都知道IPv4是一个32位4字节的整数,一共有大约43亿个IP地址。但由于要扣除网络号、广播地址、组播地址、私有地址、环回地址等,实际可分配给主机的地址远少于43亿。而且像路由器这种网络设备的每个接口也需要占用IP地址,这进一步减少了可分配给主机的数量。CIDR虽然提高了IP地址的利用率,但IP地址的总数上限没有提升,依然不够用。这时候有三种解决方案:
-
动态分配IP地址:通过DHCP等技术,在设备接入网络时临时租用一个IP地址,断开后该IP可被其他设备使用。这样同一个MAC地址的设备,每次接入互联网时获取的IP地址不一定是相同的。
-
NAT技术:允许多个设备共享一个公网IP地址访问互联网。
-
IPv6:IPv6与IPv4彼此不兼容,IPv6使用16字节(128位)来标识IP地址,地址总数约为 21282128 个(约 3.4×10383.4×1038 个),可以给地球上的每一粒沙子分配一个IP,从根本上解决了地址短缺问题。
1.3私有IP和公网IP
RFC1918规定了用于组建局域网的私有IP地址为:10.*,前8位是网络号(10.0.0.0/8);172.16.0.0到172.31.255.255,前12位是网络号(172.16.0.0/12);192.168.*,前16位是网络号(192.168.0.0/16)。除去这些地址范围的其他地址都称为公网IP(或公网IP地址)。我们日常使用的家庭、企业网络通常都使用私有IP地址(内网),通过路由器NAT转换后才能访问公网上的服务器。
那么内网又是怎么通信的呢?首先,路由器有两个及以上的网卡,因此拥有两个及以上的IP地址。一般来说,路由器的IP地址分为子网IP和WAN口IP:子网IP用于在子网内通信,而WAN口IP可能是上一级子网的内网IP,也可能是公网IP。在一个子网内的主机想向公网的一台主机发送信息,会经过以下流程:主机查找自己的路由表,找不到目标IP对应的条目,则将数据发送给默认路由(也就是本子网的路由器)。子网路由器收到数据后,执行NAT转换,将源的私有IP地址和端口替换为路由器WAN口IP地址和新分配的端口,并记录映射关系。然后路由器查找自己的路由表,如果仍找不到目标IP,就继续发送给它的默认路由(WAN口所在子网的网关)。重复上述步骤,直到数据到达WAN口IP为公网IP的路由器。之后数据在公网内通过路由协议逐跳转发,最终到达目标主机所在局域网的入口路由器。目标局域网的路由器根据目标IP(可能是公网IP或经过端口映射后的内网IP)将数据转发给目标主机。
在一个局域网内,不同WAN口IP的路由器所连接的子网IP是可以相同的(例如多户家庭都使用192.168.1.0/24)。这是因为私有IP地址只用于子网内部通信,不会影响上层网络或公网。前提是这些子网之间没有直接路由需求,否则需要额外配置。通过这种方式,结合NAT技术,极大地缓解了IPv4地址不足的问题。
1.4理解公网
数据报是怎么在公网传输的呢?数据在公网和内网上的路由原理没有本质区别,都是查找路由表决定下一跳。查找路由表时,路由器会拿目的IP与路由表条目中的网络掩码按位与,得到网络号,再与该条目的目标网络进行对比,决定下一跳的位置。不同的路由表条目可以有不同的网络掩码,也就是说公网中的网络前缀长度并不是固定的。实际的路由选择使用的是最长前缀匹配原则,即路由器会在所有匹配的条目中选择掩码最长(网络号最精确)的那一条作为转发依据。为了减少路由表条目数量,公网中大量使用路由聚合,例如一个大的ISP可能对外通告一个8位掩码的大前缀(如1.0.0.0/8),而内部再将这个地址块细分为10位或16位掩码的更小前缀分配给下级网络。这种层次化的地址分配和聚合机制保证了公网路由的可扩展性,但路由器在实际查表时仍然是统一按照最长前缀匹配来进行。