Linux之IP协议
一.IP协议
在上篇我们了解了传输层的协议TCP和UDP后我们现在就该继续往下学习网络层的协议了,对于网络层的协议我们只需要学习IP协议即可。在了解IP协议的报文格式之前我们先结合传输层协议的TCP和UDP来进一步理解网络层IP协议的作用
1.1IP协议的作用
我们知道用户传输的数据会从应用一层一层的封装再传输到对方主机中经由一层一层的解包从而得到传输得数据,所以每一层都会有其对应的作用。比如应用层的作用就是给用户提供一系列的服务也就是我们的各种应用软件,应用层协议完成的工作就是规定传输的时候数据的格式,传输层呢就是提供应用程序之间的通信不同的传输层协议就是完成通信的方式不同,所以也就造成不同的传输层协议应用的场景不同。在完成了通信后网络层就需要标志出互联网中每台主机从而达到通信的双方不会出错。而IP协议就是网络层中一种实现方法它首先完成了对互联网中每台主机的标志并且让这些标志都是独一无二的。所以我们可以将应用层协议当作不同快递公司的软件,而物流公司就是各种传输层协议最后我们填写的地址就是网络层协议。应用层给用户提供服务传输层实现具体传输流程而网络层则是提供标明唯一的目的地。
我们还可以从下面这张图里来具体的说一下
例如我们想要去北京的天安门那么我们就可以将目标地址划分成两部分目标城市和目标景点也就是分为北京和天安门。因为如今互联网规模的宏大所以源主机和目标主机大概率不在一个子网中也就是说我们需要跨网络来传输数据所以IP地址我们也可以将其划分成两部分也就是目标网络和目标主机。所以IP地址=目标网络+目标主机。
所以从图中我们可以大概了解传输的流程首先主机B将数据传给路由器F然后路由器F发现主机C和主机B不是一个子网的所以将其抛给路由器G然后发现也不存在路由器G的子网中从而重复传给路由器H,C,直到路由器C发现IP地址中的目标网络和路由器D是相同的所以传给路由器D最后路由器D发现报文中的IP地址中的目标主机就是自己子网的主机C所以传给主机C。
1.2IP协议的报文格式
在大概了解了IP协议的作用后我们现在就来看看IP协议是如何完成自己的作用的。所以我们来看看IP协议的报文格式。
在看协议报头格式时我们一样提出三个问题:如何实现报头和有效载荷(正文)的分割?有效载荷如何向上交付?怎么保证正文被读完了?我们来一个一个的解答这三个问题顺便先介绍几个报文格式中的几个字段的作用。
- 如何实现报头和有效载荷的分割
在报文中存在一个4位的首部长度这个字段也存在于TCP协议中,这个字段就是标明了你报头的长度只是我们需要将其值再乘4而已。也就是说IP协议中报头最长是15*4=60字节。 - 有效载荷如何向上交付
在IP协议中有一个8位的协议字段,这个字段记录了上层也就是传输层协议的类型有了传输层协议的类型我们自然可以将有效载荷向上交付了。 - 怎么保证正文被读完了
IP协议中还存在一个16位的总长度字段,这个字段记录了整个报文的长度所以我们只需要读取4位首部长度和总长度就可以完成将报头和有效载荷分离并且可以将有效载荷读取完全。
这三个字段是IP协议中解决这三个问题的方法,接下来我们来介绍几个比较好理解在其他协议中也出现过的字段
- 选项
选项字段在TCP协议中也出现过用来标明IP协议中各个字段的额外属性我们是否使用,最长是40字节那么我们如果将报头去掉选项字段报头就是20字节。所以报头的长度总体来说就是20-60。 - 32位源IP地址和32位目的IP地址
这两个字段也非常的好理解他们俩的作用就是标明源主机的IP地址和目的主机的IP地址。 - 16位首部检验和
这个字段也是老熟人了,其作用就是利用CRC来判断报头是否损坏是否不符合要求 - 4位版本
对于IP协议如今我们其实是将其分为两类:IPv4和IPv6。这个字段就是来标明使用的IP协议的版本对于IPv4来说这个字段就是4。
那么为什么IP协议会被分为两类呢?这就要提到32位IP地址这个字段,我们利用这个字段来标明主机的IP地址所以IP地址的范围就被划分成了0-2的32次方也就是0到42亿这个范围。那么根据这个范围说明全世界最多就只能存在42亿个IP地址这个数量在当时创建IP地址的年代来说是一个很庞大的值了但是没有想到互联网发展的速度太快了并且IP地址也不是与电脑进行关联而是与网卡进行关联所以造成一台电脑可能拥有多个IP地址。这也就造成了IP地址的数量越来越多直到发现这42亿的数量好像不太够用为了解决这个问题有人就创造出了IPv6也从此将IP地址分为了IPv4和IPv6。那么IPv6是如何解决这个问题的呢?IPv6地址使用以冒号分隔的十六进制数字。它分为八个16位块,构成一个128位地址方案。所以IPv6的地址范围是0-2的128次方也就是168亿个地址。虽然IPv6地址也是有限的但是这168亿地址已经够我们再用很久了。
这里还有提一个题外话虽然如今IP地址被分为IPv4和IPv6两种但是国际上通常使用的还是IPv4因为还有人创造出了网络地址转换也就是NAT技术来解决地址耗尽的问题,这个技术一定程度上缓解了IPv4地址耗尽的问题。但是止渴不解渴虽然IPv6国际使用率不高其仍然是需要大力发展的技术而如今在国际上使用IPv6最多的就是我们国家了。 - 8位服务类型
这8位服务类型分为三部分:3位优先权字段,4位TOS字段和1位保留字段。其中3位优先权字段已经被弃用了而1位保留字段我们必须设为0所以真正能让我们根据场景不同修改的字段只有4位TOS字段,而这4位字段的四位分别代表了最小延迟,最大吞吐量,最高可靠性,最小成本。这四种情况各自冲突只能将其一个设为1,具体是设置哪个为1则是根据应用层的应用程序不同来设置例如对于ssh/talnet来说最小延迟比较重要,对于ftp来说最大吞吐量比较重要。 - 8位生存时间
这个字段是数据报到达目标主机的最大报文跳数,什么意思呢其实就是从源主机到目的主机中数据报最多可以经过多少个路由器,正常来说这个值是64只要经过一个路由器就会将其-1直到为0。如果其值为0了那么这个数据报就会被丢弃,这个字段主要就是为了防止路由循环也就是数据报反复在两个路由之间跳跃。
在介绍完了这些字段之后就只剩下了16位标志3位标志和13位片偏移这三个字段了。要想介绍这三个字段我们需要再了解一个知识:IP协议的分片和组装。
1.3IP协议的分片和组装
1.3.1分片
在了解这三个字段之前我们先了解什么叫做分片为什么会有分片。首先分片是什么,分片是指当IP协议的报文超过了网络的最大传输单元限制即MTU后系统就会将这段报文拆分成多份来分别传输,而这个MTU是网络层的下一层数据链路层对网络层的限制也就是说MTU其实是数据链路层所能接受的最大数据长度。
所以分片简单来说就是对超过MTU的数据报拆分成多份来分别传输,分片的原理很好理解但是分片的过程不是那么的简单的。我们可以来思考一下想要完成分片我们需要解决哪些问题:首先如何判断当前数据报是被分片的其次如何通过标识来分辨出不同数据报的分片最后怎么知道这个分片是从原数据报的哪个位置拆分出来的。
只要解决这三个问题那么就能很好的完成分片了,三个问题三个字段所以IP协议直接将解决办法设置成了三个字段,那么我们就来一个一个的分析。
- 3位标志
3位标志中的三位分别代表了不同的含义:第一位保留它是不使用的。第二位是DF位也就是Don’t Fragment如果DF位为1说明这个数据报不分片此时如果数据报的数据超过MTU则直接将数据报丢弃那么DF位为0则说明这个数据报可以分片。第三位是MF位也就是More Fragment如果MF位为1说明这个分片不是最后一个分片如果为0说明此分片是原数据报的最后一个分片类似一个结束标志位。所以我们利用3位标志解决了第一个问题即怎么判断当前数据报是被分片的。 - 16位标志
这个16位的标志位是主机发送的数据报的唯一的标志,要注意是数据报的标志不是分片的标志并且如果此数据报被分片了那么各个分片的标志也是相同的。所以这样就很好的解决了怎么分辨不同数据报的分片。 - 13位片偏移
在解决了如何判断分片以及分辨各数据报的分片后我们现在就要来解决怎么知道该分片是从原数据报的哪个位置拆分出来的即可,IP协议利用的是13位片偏移这个字段内存储的是当前分片相对于原报文开始处的偏移量并且要注意这个偏移量是以8字节为单位的所以在读取到片偏移后我们只需要将其除以8就能得到该分片的偏移量了。同样又因为偏移量是以8字节为单位所以每个分片的报文长度也必须是8的整数倍。
在了解了这三个字段后我们就能得知数据报是如何进行分片的了,当一个IP数据报的大小超过MTU时IP层就会将该数据报分割成多个较小的片段,对于这些片段IP层也会给他们添加各自的报头也会设置其对应的16位标志3位标志以及13位片偏移,最后会将这些片段独立的传输出去而这些片段也会自由的选择路由。
1.3.2组装
在了解了IP层是如何进行分片的之后我们还需要了解对方是如何进行组装的。
对于对方IP层只需要先接收这些分片之后根据16位标志来挑选出属于同一个数据报的分片之后再根据片偏移字段来将这些分片进行排序最后只要判断这些分片中间没有残缺并且最后一个分片的MF位是0就可以将其重新组装成一个完整的IP报文再传递给上层的传输层即可。注意:在分片的时候有那三个问题同样在组装的时候也需要根据那三个问题来判断分片是否能组成一个完整的报文因为上层是不关心你传递上去的报文是否是完整的它只负责接收然后再进行它自己的操作所以IP层必须完成判断组装的报文是否完整这个工作。通常是根据MF位以及片偏移字段来完成的。
二.网段划分
在上面我们提到过IP地址被分为了两部分:网络号和主机号。通过网络号来判断主机处于哪个子网中通过主机号确定是子网中的哪台机器。并且我们了解了我们大部分我们现在用的都是IPv4地址而IPv4地址以点分十进制表示,每个部分代表一组构成8位地址方案的8位地址。所以我们日常见的IP地址都是以xxx.xxx.xxx.xxx的形式来表达出来的。
从图中我们也可以看出来子网的构建通常都是利用路由器来完成的而一个子网中可能会有多台主机我们只需要合理的设置网络号和主机号就能完成子网的搭建也能保证子网中的每台主机都有着不同的IP地址,但是当子网中的主机变多了之后如何对这么多的IP地址进行管理呢?难不成全部都手动管理吗这肯定是不可能的,所以为了方便管理各子网中的IP我们发明了一个叫做DHCP的技术,DHCP能够自动的给添加到子网中的主机分配一个IP地址从而完成了对子网IP地址的管理。对子网IP地址的管理是完成了但是我们要知道全世界用的都是同一套网络地址所以我们还需要解决对全世界IP地址的管理也就同时又因为使用各个IP地址的目的不同所以国际上采用了网段划分的方法来完成对全球IP地址的划分。
最初我们是采用了一种将各个IP地址分成五类即ABCDE类的方法,根据使用目的不同以及公司 大小不同来申请不同类型的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
根据你的目的不同你所能申请的IP地址也不同,A类地址基本都是由国家申请所用而企业大部分申请的都是B类的IP地址。这样一来这种划分方法的局限性就出现了,所有企业都去申请B类的IP地址的并且由于B类IP地址的一个子网中理论能有六万五千多个主机但是在实际使用中不太可能有这么多的主机数量从而产生IP地址浪费。企业都去申请B类地址了但是还造成了浪费那么这个划分方案不就是不合理的吗。
所以在意识到划分方案不合理后又设计出了一种新的网段划分的方法:CIDR
在上面那种方法的基础上我们新增了一个子网掩码,子网掩码也是一个32位的整数并且也是以八位做分割再加上点符号子网掩码的作用就是来区分出网络号和主机号而如何使用子网掩码我们可以类比我们之前学习权限的时候学习过的权限掩码umask,我们只需要将子网掩码和IP地址按位与就能得到一个新的整数这个整数就是网络号。通常网络号的最后几位是0而主机号就是这最后几位。我们来举个例子吧
要注意这个例子的主机号是最后的八位不代表所有的主机号都是最后八位,大家以每四位为一组看网络号的尾端有几组四位全为0的那就是它的主机号。例如如果IP地址是140.252.20.68子网掩码是255.255.255.240那么网络号就是140.252.20.64最末尾的64换算成二进制就是0100 0000,所以主机号就是最后的四位那么该IP地址的子网地址范围就是140.252.20.64-140.252.20.79。
2.1特殊的IP地址
在学习了网段划分后有几个特殊的IP地址希望大家可以了解
- IP地址中的主机地址全部设为0,就成为了网络号也就是代表这个局域网
- IP地址中的主机地址全部设为1,就成了广播地址我们可以通过这个广播地址给处于同一个链路中的主机发送数据报
- 127.*的地址一般都是本地地址用于本机环回(loop back)测试通常是127.0.0.1。
2.2IP地址的数量限制
在上面讲述IPv4和IPv6的区别的时候我们提到过IPv4地址的数量问题,我们上面说的CIDR技术由于提高了IP地址的利用率减少了浪费所以一定程度上缓解了IPv4地址的问题但是治标不治本。在2011年,全球互联网编号分配机构(IANA)分发了IPv4地址空间的最后一块。2015年,IANA正式宣布美国已用完IPv4地址。所以IPv4的地址数量问题是如今我们需要解决的一大问题因为现在百分之90以上的互联网都还是用的是IPv4地址,那么为了解决这一大问题现在发明了三种技术来解决这个问题:动态分配IP地址,NAT技术,IPv6。其中IPv6我们已经解释过了所以我们就来简单介绍一下另外两种技术。
- 动态分配IP地址
只给接入网络的设备分配 IP 地址. 因此同一个 MAC 地址的设备, 每次接入互联网中, 得到的 IP 地址不一定是相同的。 - NAT技术
NAT 能够将私有 IP 对外通信时转为全局 IP,也就是就是一种将私有 IP 和全局IP 相互转化的技术方法。NAT技术在后面学习完数据链路层后我们还会仔细介绍
2.3私有IP地址和公有IP地址
我们可能都听说过在公司中有自己的内网什么的,这个内网其实就是公司申请了一个IP地址后再利用这个IP地址创建的子网,对于一个组织创建的子网也就是局域网如果这个子网中的主机是只和子网内的主机进行通信不和外部的网络进行通信的话理论上这些主机的IP地址任意都可以因为只在子网中通信嘛,但是RFC1918规定了组建子网的IP地址叫做私有IP地址。
- 10.*,前 8 位是网络号,共 16,777,216 个地址
- 172.16.到 172.31.,前 12 位是网络号,共 1,048,576 个地址
- 192.168.*,前 16 位是网络号,共 65,536 个地址
包含在这个范围内的IP地址都是私有IP地址其余的是公有IP地址,不信的话大家可以利用ipconfig命令在自己电脑的终端中查询自己电脑的IP地址是否是私有IP地址。
对于私有IP地址我们还需要知道私有IP地址是无法访问公有IP地址的那么大家就有疑问了我们平时不是也上网吗对于各种软件不也可以访问他们吗?这就要提到我们正常家庭中想要组建子网的一个必不可少的东西:路由器。当我们用电脑访问各种软件时我们其实就是要访问这些软件的公司的服务器而这些服务器基本都是公网IP但是我又说私有IP无法访问公有IP地址所以在访问的过程中我们肯定会经过一些步骤变为公有IP。在我上面介绍私有IP地址时大家再回过头看的话能发现我说的是在有公有IP地址的基础上组建自己的子网而我们想要组建子网又必须用上路由器所以在路由器中其实存储了两个IP地址:子网的IP地址也就是LAN口IP和WAN口IP。
这个WAN口IP可能是私有IP也有可能是公有IP因为家用的路由器也是由运营商提供的也就是说家用路由器其实也处于运营商路由器创建的一个子网,而运营商路由器的WAN口IP就是一个公有IP。
所以当我们访问软件的服务器的过程其实是这样的。
我们也可以用一张图来表达这个过程
在这个过程中我们需要注意几个问题
- 不同的路由器子网IP可能是相同的这也是为什么私有IP地址无法出现在公网中
- 路由器WAN口的IP可能是私有IP也有可能是公有IP一般来说家用的路由器的WAN口IP还是私有IP,运营商路由器的WAN口IP是公有IP
- 当主机需要和公网进行通信时,请求上传的时候每个路由器都需要把源IP改为自己的WAN口IP响应下传也相同。这种逐级传递更换IP地址的技术就是NAT技术。
- 如果我们想要拥有一个带有公有IP的服务器我们可以在线上购买云服务器。
三.路由
路由其实就是主机上传数据报后在不同的设备中在网络中一跳一跳直到达到目的IP的行为也就是一种在复杂的网络中寻找一条通往终点的路径的行为。
而这个行为中的每一跳其实就是我们刚刚讲述的主机与公网IP通信的过程中的数据报从主机到路由器,从路由器到路由器这一过程。那么想要找到目的IP主机和路由器就必须规划数据报下一跳去哪里所以想要解决这一问题每个节点也就是主机和路由器中存储了一个路由表。路由表中存储了当前节点记录了哪些IP地址以及如果这些IP地址都不满足的话将数据报传递到哪里去。我们可以用route命令来查看我们的路由表。
在传输数据报时每个节点会用目的IP地址和每行的子网掩码来生成一个网络地址如果网络地址和当前行的目的网络地址相同则直接利用发送接口发送过去如何不同则继续往下生成新的网络地址,如果全部不匹配的话就会按照缺省路由条目也就是图上的第一行来找到发送接口发送到下一个路由器。
例如我们发送的数据报的目的IP地址是192.168.198.60,目的地址会先和第二行的子网掩码按位与生成192.168.198.0发现于第二行的目的网络地址不同然后再与第三行的子网掩码按位与生成192.168.198.0之后发现于第三行的目的网络地址相同随后找到对应行的Iface也就是发送接口所以数据报会从ens33接口发送出去。