Linux网络:网络层之IP协议

一、IP 协议

IP(Internet Protocol,网际互连协议)

在这里插入图片描述

1.基本概念

  • 主机:配有 IP 地址,能进行路由控制的末端节点设备。
  • 路由器:配有 IP 地址,能进行路由控制的中间节点设备。
  • 节点:主机和路由器的统称。

2.格式

在这里插入图片描述

说明:
 ① 源 IP 地址和目的 IP 地址:表明报文是哪个主机发的,要发到哪个主机。
 ② 首部长度:表示 IP 报头的长度,基本单位是 4 字节。
 ③ 选项:IP 报头中允许携带额外的选项。
 ④ 总长度:表示整个 IP 报文的长度。
 ⑤ 协议:表示上层协议的类型。
 ⑥ 首部检验和:如果检验不通过,就会直接丢弃整个报文。
 ⑦ 版本:指定 IP 协议的版本,对于 IPv4 来说,就是 4 。
 ⑧ 服务类型:3 位优先权字段(已经弃用),4 位 TOS 字段和 1 位保留字段(必须置为 0)。4 位 TOS 分别表示:最小延时、最大吞吐量、最高可靠性、最小成本。这四者相互冲突,只能选择一个。
 ⑨ 生存时间:指定 IP 包在被路由器丢弃之前所允许的最大报文跳数,一般是 64 。每次经过一个路由,TTL -= 1 。若减到 0 还没到达,该报文就会被丢弃。这个字段主要是用来防止出现路由循环。
 ⑩ 标识:唯一地标识 IP 报文(若不出现分片,不同的报文的标识是不一样的;若出现分片,分片报文的标识是一样的)。
 ⑪ 标志:第一位保留,第二位表示禁止分片(若置为 1 ,表示若报文长度超过 MTU ,IP 模块就会丢弃该报文),第三位表示更多分片(若置为 1 ,表示后面还有分片报文;若置为 0 ,表示后面没有分片报文。如果报文进行了分片,则除了最后一个分片报文置为 0 以外,其余分片报文均置为 1)。
 ⑫ 片偏移:分片相对于原始数据开始处的偏移。表示当前分片在原始数据中处在哪个位置(这里的原始数据,指的是 IP 从上层收到的 TCP 报文或 UDP 报文,不包含 IP 首部)。片偏移 * 8 等于 实际偏移的字节数。

由于 IP 报头的标准长度是 20 个字节,所以首部长度的值一般是 20 / 4 = 5 ,即二进制的 0101 。
首部长度的最大值是 15 ,即 IP 报头的最大长度是 15 * 4 = 60 个字节,意味着选项最多是 60 - 20 = 40 个字节。

  • IP 的解包:当读到一个完整的 IP 报文,先提取它的前 20 个字节,从前 20 个字节里分析出首部长度的值(IP 报头的长度),若首部长度的值等于 20 个字节,则说明没有选项字段,前 20 个字节就是报头,剩下的就是有效载荷;若首部长度的值大于 20 个字节,则再读取选项字段,读完选项字段后,剩下的就是有效载荷。

  • IP 的封装:给有效载荷添加上报头。

  • IP 的分用:把报头和有效载荷分离后,根据报头中的协议字段,把有效载荷交付给上层的某个具体协议。

对于 IP 报文,报文和报文之间的边界是明确的,根据首部长度和总长度,就能够区分自身报文的报头和有效载荷。

3.分片和组装

为什么会分片?
数据链路层中的以太网帧,对其携带的有效载荷的长度是有大小限制的,最大长度一般是 1500 字节,称之为以太网的 MTU(Maximum Transmission Unit,最大传输单元)。换言之,IP 向下交给数据链路层的报文的大小不能超过 MTU 。
所以,IP 报文如果太大,会在网络层里进行分片,最后分为几个 IP 报文。
实际上,IP 报文分片不是大部分情况,而是一种特殊情况。

为什么分片要在网络层里进行?
因为如果分片,分出来的 IP 有效载荷也要添加 IP 报头。要添加 IP 报头,处理者必须得对它很了解,只有网络层最了解,而数据链路层不关心而且也不需要关心。除此之外,在网络层里进行分片,可以做到不提高耦合度。

谁来组装?
因为分片是在网络层里做的,所以组装也是在网络层里做。若 IP 报文在本端的网络层里分片了,就会在对端的网络层里组装。

在本端,传输层向下交给网络层的数据是什么样子,那么在对端,网络层向上交给传输层的数据也就是什么样子,这就相当于在网络层里进行的分片和组装,对传输层而言是隐藏的。

如何分片?
在网络层里,将大的 IP 报文的有效载荷分为几份(使分片的数量最少),然后给每份有效载荷都添加上 IP 报头(标识一样,片偏移按规则来定),最终分为几个 IP 报文。

分片的例子:
比如在网络层里的 IP 报文,其长度是 3420 字节(3400 字节的有效载荷 + 20 字节的报头),由于数据链路层的 MTU 的限制,所以该 IP 报文需要在网络层里进行分片,为了使分片的数量最少,将 3400 分为三份,即 1480 、1480 和 440 ,然后再给这三份有效载荷都添加上 20 字节的 IP 报头,所以最后总共分为了 3 个 IP 报文,大小分别是 1500 、1500 和 460 字节。

接收端如何区分正常独立的报文和分片报文?
接收端只需根据报文的片偏移和更多分片进行判断:
 ① 对正常独立的报文:它的片偏移为 0 且更多分片为 0 。
 ② 对分片报文:它的片偏移不为 0 或更多分片为 1 。

对分片报文:
 ① 若是第一个,它的片偏移为 0 ,更多分片为 1 。
 ② 若是中间的,它的片偏移不为 0 ,更多分片为 1 。
 ③ 若是最后一个,它的片偏移不为 0 ,更多分片为 0 。

接收端如何确认是否收全了分片报文?
注:此处的分片报文都是同一标识的分片报文。
根据片偏移和更多分片,进行确认是否收全了分片报文。
只要收到片偏移为 0 的报文和更多分片为 0 的报文,第一个分片报文和最后一个分片报文就收到了,然后再根据片偏移,对所有的分片报文进行升序排序,若每一个报文的片偏移加上该报文有效载荷的长度 / 8 的值,都等于下一个报文的片偏移,则证明报文已经连续,确认收全了分片报文。

接收端如何知道分片报文是否丢失了呢?
丢包无外乎有三种情况:第一个丢了,中间的丢了,最后一个丢了。
 ① 只要发现片偏移为 0 的报文没有,就是第一个丢了。
 ② 只要发现更多分片为 0 的报文没有,就是最后一个丢了。
 ③ 只要发现存在一个报文的片偏移加上该报文有效载荷的长度 / 8 的值,不等于下一个报文的片偏移,就是中间的丢了。

如何组装?
假如没有丢包,同一标识的分片报文都被接收端收到了,接收端根据片偏移对同一标识的分片报文进行升序排序,然后进行组装。

组装的例子:
比如在网络层里的同一标识的分片报文,根据片偏移对其进行升序排序后:
在这里插入图片描述
注:这里只标出了分片报文的有效载荷,没有标出报头。

分片报文的更多分片分别为 1 、1 、0 。

分片会增加丢包的概率
如果在路由时丢了其中的一个或几个分片报文,对端的网络层在进行组装时都会组装失败,只能将其余的分片报文全部丢弃。

分片时把一个原始报文分成了好几个报文,只要丢了其中的任何一个,就相当于丢了一整个原始报文,通过计算可以知道,这个丢包概率是增加了的,所以说分片会增加丢包的概率。

如果是 TCP ,情况也还不算坏,因为 TCP 具有可靠性,会超时重传。如果是 UDP ,那么就真的丢包了,因为 UDP 是不可靠的。
因此,IP 报文分片不是大部分情况,而是一种特殊情况。

二、网段划分

IP 地址分为两个部分:网络号和主机号。

  • 网络号:保证相互连接的两个网段具有不同的标识。
  • 主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号。

IPv4 地址是 32 位,网络号和主机号其实就是对这 32 个比特位进行了划分,前面的若干个比特位标识网络号,剩下的比特位标识主机号。

在这里插入图片描述

一个网段,可以理解为一个局域网。

  • 在不同的网段中,网络号是不一样的。
  • 在同一个网段内,所有主机的网络号是一样的。

所以,在不同的网段中,可能存在相同的主机号,但是由于网络号不一样,所以 IP 地址也不会重复。

如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致,但是主机号必须不能和子网中的其他主机重复。

上图的这两个网段是通过路由器连接起来的,路由器会记住它所连接的两个网段的网络号。因为路由器横跨两个网段,所以在每个网段看来,路由器都是其中的一台主机,所以也必须配有对应的 IP 地址,所以上图的路由器必须得配有两张网卡,每张网卡里各自配一个 IP 。

一般而言,在一个网段内,主机号为 1 的通常是路由器。

因为路由器的存在,所以就可以将数据从一台主机转发给另一台主机。

通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的 IP 地址都不相同。
但是手动管理子网内的 IP ,是一件相当麻烦的事情。现在有一种技术叫做 DHCP(Dynamic Host Configuration Protocol ,动态主机配置协议),能够自动地给子网内新增的主机节点分配 IP 地址,避免了手动管理 IP 的不便。一般的路由器都带有 DHCP 功能,因此也可以将路由器看做一个 DHCP 服务器。

查找的过程,本质是排除的过程!
网段划分的本质,是为了提高查找效率,降低查找的难度,便于组网!

过去曾经提出一种划分网络号和主机号的方案,把所有的 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 到 223.255.255.255 。
 D 类:224.0.0.0 到 239.255.255.255 。
 E 类:240.0.0.0 到 247.255.255.255 。

上面的这种方案叫做分类划分法

随着 Internet 的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请 B 类网络地址,导致 B 类地址很快就分配完了,而 A 类却浪费了大量地址。

例如,申请了一个 B 类地址,理论上一个子网内能允许 6 万 5 千多个主机。A 类地址的子网内的主机数更多。然而实际网络架设中,不会存在一个子网内有这么多主机的情况,因此大量的 IP 地址都被浪费掉了。

因此,针对 IP 地址被浪费的这种情况,又提出了新的划分方案,称为 CIDR(Classless Inter-Domain Routing,无类别域间路由):

  • 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号。
  • 子网掩码也是一个 32 位的正整数,用二进制表示就是前面全 1 后面全 0 。
  • 将 IP 地址和子网掩码进行按位与操作,得到的结果就是网络号
  • 网络号和主机号的划分与这个 IP 地址是 A 类、B 类还是 C 类无关。

通过设置子网掩码,将一个子网不断地再进行划分子网,此时可用主机号变少,相当于对 IP 地址的使用更精细了。

下面举两个例子:
在这里插入图片描述

注:上面地址的表示方式都是点分十进制。

将 IP 地址和子网掩码进行按位与运算,可以得到网络号,主机号从全 0 到全 1 就是子网的地址范围。

IP 地址和子网掩码还有一种更简洁的表示方法,例如 140.252.20.68/24 ,表示 IP 地址为 140.252.20.68 ,子网掩码的高 24 位是 1(即 255.255.255.0)。

我们划分子网的方案是,先用粗粒度的分类划分法进行划分,然后对每个子网,给路由器都设置上子网掩码,这样就可以通过调整 IP 地址网络号和主机号的位数,来限制一个子网中允许构建的主机数,不对 IP 地址造成过多的浪费。

特殊的 IP 地址:

  • 将 IP 地址中的主机号全部设为 0 ,就成为了网络号,代表这个局域网。
  • 将 IP 地址中的主机号全部设为 1 ,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。

所以实际上,一个子网只能容纳【 [2^(主机号位数)] - 2 】台主机。

  • 127.* 的 IP 地址用于本机环回(loop back)测试,通常是 127.0.0.1 。

三、IP 地址的数量限制

我们知道,IP 地址(IPv4)是一个 4 字节 32 位的正整数,那么一共只有 2 的 32 次方 个 IP 地址,大概是 43 亿左右。而 TCP/IP 协议规定,每个主机都需要有一个 IP 地址。

实际上,由于一些特殊的 IP 地址的存在,数量远不足 43 亿,另外 IP 地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个 IP 地址。

CIDR 减少了 IP 地址的浪费,但并没有增加 IP 地址个数的绝对上限,所以仍然是不够用的。这时候有三种方式来解决:

  • 动态分配 IP 地址:只给接入网络的设备分配 IP 地址。因此同一个 MAC 地址的设备,每次接入互联网中,得到的 IP 地址不一定是相同的。
  • NAT 技术。
  • IPv6:IPv6 并不是 IPv4 的简单升级版,这两个协议彼此并不兼容。IPv6 用 16 字节 128 位的正整数来表示一个 IP 地址。但是目前 IPv6 还没有普及。

四、私有 IP 地址和公网 IP 地址

如果一个组织内部组建局域网,IP 地址只用于局域网内的通信,而不直接连到 Internet 上,理论上使用任意的 IP 地址都可以。
但是 RFC 1918 规定了用于组建局域网的私有 IP 地址,只能是如下的几类:

  • 10.* :前 8 位是网络号,共 16,777,216 个地址。
  • 172.16.* ~ 172.31.* :前 12 位是网络号,共 1,048,576 个地址。
  • 192.168.* :前 16 位是网络号,共 65,536 个地址。

包含在这个范围中的,都只能是用于组建局域网的私有 IP 。在这个范围之外的,都只能是用于组建公网的公网 IP(或全局 IP)。

下图是一个简单的网络关系(但是能说清楚):

在这里插入图片描述

  1. 一个路由器可以配置两个 IP 端口:一个是对内的 IP 端口,称为 LAN 口 IP(子网 IP 或 私有 IP);一个是对外的 IP 端口,称为 WAN 口 IP 。
  2. 路由器是可以用来组建局域网的。连接路由器 LAN 口的主机,都从属于当前这个路由器的子网。
    所有用户在接入网络时,不是使用公网 IP 直接接入公网的,而是使用私有 IP 以局域网的形式接入网络的。
  3. 不同路由器的子网 IP 其实都是一样的(通常都是 192.168.1.1),子网内的主机 IP 不能重复,但是不同子网的子网 IP 地址可以重复。
  4. 路由器和路由器之间也可以组建子网。每一个家用路由器,又作为运营商路由器的子网中的一个节点。这样的运营商路由器可能会有很多级,最外层的运营商路由器的 WAN口 IP 就是一个公网 IP 。
  5. 子网内的主机需要和外网进行通信时,路由器将 IP 首部中的源 IP 地址进行替换(替换成 WAN 口 IP),这样逐级替换,最终数据包中的源 IP 地址成为一个公网 IP 。换言之,一台主机的 IP 数据包在对外发送时,数据包的源 IP 地址可能一直在被中间路由器替换。这样的技术称之为 NAT 技术(Network Address Translation ,网络地址转换)。
  6. 如果希望我们自己实现的服务器程序,能够在公网上被访问到,就需要把程序部署在一台具有外网 IP 的服务器上。

五、路由

路由,本质就是在复杂的网络结构中,找出一条通往终点的路线。

路由的过程,就是一跳一跳的过程。

所谓的一跳,就是数据链路层中的一个区间,具体在以太网中指从源 MAC 地址到目的 MAC 地址之间的帧传输区间。
在这里插入图片描述

IP 数据包的传输过程,跟问路一样:
 ① 当 IP 数据包到达路由器时,路由器会先查看数据包的目的 IP 。
 ② 路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器。
 ③ 反复执行上面的过程,一直到达目的 IP 。

在这里插入图片描述

如何判定当前这个数据包该发送到哪里呢?这就依靠每个节点内部维护一张路由表

通过route命令,可以查看主机 OS 维护的路由表(可以把主机当作一个路由器)。
在这里插入图片描述带上 -n 选项,将名称转化成数字:在这里插入图片描述
说明:
 ① Destination:目的网络地址。
 ② Genmask:子网掩码。
 ③ Gateway:网关。
 ④ Iface:发送接口。
 ⑤ Flags:U 标志表示此条目有效(可以禁用某些条目),G 标志表示此条目的下一跳地址是某个路由器的地址(网关),没有 G 标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。

当 IP 数据包到达路由器时,路由器就会用该数据包的目的 IP ,依次与路由表中的 Genmask 进行按位与操作,然后将结果与在同一条目中的 Destination 进行比对:

  • 若相等,则通过 Iface 转发给 Destination 。
  • 若都不相等,则通过 Iface 转发给 default(默认下一跳)。


转发过程例1:如果要发送的数据包的目的地址是 10.0.20.3 。先跟第二行(在这里是从第二行开始)的子网掩码做与运算得到 10.0.20.0 ,发现与第二行的目的网络地址相符,因此从本机 eth0 接口发送出去。由于 10.0.20.0 正是与本机 eth0 接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发。

转发过程例2:如果要发送的数据包的目的地址是 202.10.1.2 。依次和路由表前几项进行对比,发现都不匹配,所以最终按缺省路由条目,从本机 eth0 接口发出去,发往 10.0.20.1 路由器,由 10.0.20.1 路由器根据它的路由表决定下一跳地址。

路由表生成算法:
路由表可以由网络管理员手动维护(静态路由),也可以由路由器通过一些算法自动生成并且能够根据实际情况的变化适时地进行调整(动态路由)。

IP 最大的意义,在于路径选择!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值