【Linux】网络层

目录

IP协议

协议头格式

网段划分

2中网段划分的方式

为什么要进行网段划分

特殊的IP地址

IP地址的数量限制

私有IP地址和公有IP地址

路由


IP协议

在通信时,主机B要把数据要给主机C,一定要经过一条路径选择,为什么经过路由器G后,不去E而是去H,因为目的IP是主机C。

IP地址的意义:IP地址提供了一种"能力",将数据从B主机跨网络可靠地送至C主机的能力。能力是什么?是具有很大的概率做成一件事情。举一个例子,有一个教授父亲和学霸儿子,目的是让儿子考100分,如果没考到,教授父亲就要求老师重新考一次,直到考到100分。其中,学霸儿子提供执行、能力和具体的操作,教授父亲提供策略。

我们要求IP地址可靠地将数据发到目标主机(比如要求学霸儿子一定要考100)。实际上,网络层提供能力,传输层提供策略。IP协议提供不了可靠性,丢包问题由传输层来解决。


可以通过ifconfig命令查本主机的IP。

IP=网络号+主机号。如何理解?IP地址的设定是有规则的,我们这一台主机一定是隶属于某一个子网的,凡是在同一个子网里的所有的主机的IP地址都是很类似的,前面的是一样的,前面的是网络号。在路由时,先根据网络号路由,然后才是主机号。比如,唐僧在去取经的时候,唐僧永远说的是我要去西天大雷音寺面见佛祖,所以唐僧的目的地址是西天+大雷音寺,如来佛祖相当于一个进程,唐僧在路上别人告诉的都是西天怎么走,而不是大雷音寺怎么走。所以,在路上路由的都是要去的网络号,到了西天之后,才说大雷音寺怎么走,也就是主机号。再比如,学生的学号,很有规律,学院号+班级号+...,先根据学院号,再根据班级号,等等去找到这个学生。在网络世界里同样如此。

主机:配有IP地址的设备。

路由器:即配有IP地址,又能进行路由控制。

节点:主机和路由器的统称。

协议头格式

报头和有效载荷如何分离

IP报文的标准长度是20字节,4位首部长度(0-15,但是基本单位是4字节,所以首部长度范围是0-60),所以如果没有选项字段,那4位首部长度的值应该是20/4=5(0101),最多20,60的选项字段。所以,在提取IP报文时,先提取20个字节的报头,再提取4位首部长度,再乘以4,减去20字节,就是选项,然后就是数据正文。

如何分用

8位协议是TCP或UDP,到达目标主机之后,可以根据8位协议字段向上交付。


我们再来看看IP中的4位版本,通常是ipv4。IP版本有两种,ipv4和ipv6。ipv4用4字节来表示一个IP地址,用一对源IP地址、目的IP地址来表示从哪发的,到哪去。 这就是说ipv4最多能表示2^32台主机吗?是的,但是这个数量是远不够的,后来又想办法解决这个问题。

ipv6用16个字节表示一个IP地址,能表示的主机台数多很多了,但是ipv4和ipv6不兼容。ipv6无法被广泛推广(需要短时间把所有支持ipv4的都换成ipv6)。

8位服务类型:3位优先权字段(已弃用),4位TOS字段,和1位保留字段。4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。这四者相互冲突,看自己的需求更大就选哪一个。对于ssh和telnet这样的应用程序,最小延迟比较重要。

16位总长度:可以计算出自身报文长度是多少。

8位生存时间(TTL):网络世界非常复杂,没有人能够把网络的拓扑结构搞清楚。网络是人设计的,肯定会有bug,报文在经过路由传输时,可能会出现环路问题,在一个环路中循环起来,导致该报文在网络中一直存在,时间一久这个环形网络就会积攒大量报文。所以,我们要给报文设置生存时间,每经过一个路由器,这个生存时间计数器就-1,当识别到该报文的生存时间减到0时,这个报文就被丢弃掉了。


综合来看,网络中任何一个报文会包含:源IP,源端口、目的IP、目的端口,协议号。源IP和目的IP在网络层,源端口和目的端口在传输层中。在网络通信时,客户端和服务器都要有自己的套接字信息,把源IP,源端口、目的IP、目的端口都打包发过去,并且要把IP地址和端口号转换为网络序列,因为要作为报文的一部分。另外,双方在进行通信时,通过IP报头中的8位协议来判断传输层是通过TCP协议还是UDP协议传输,这就是协议号。把这样一个五元组标识一个网络通信。这就是我们为什么把网络编程称为套接字编程,因为是通过IP和端口号的标识来进行通信的。

网段划分

2中网段划分的方式

已ipv4为例,一共有2^32中排列组合,IP地址是一个有用且有限的资源,和石油天然气一样有限,所以在国际中会存在竞争关系,所以,IP地址要通过合理划分来给不同的区域,国家,组织,学校等。所以,我们的网络世界,是被精心设计过的,从硬件到软件。

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

同一个网段的主机网络号是一样的,主机号不一样。路由器横跨两个子网,在两个子网看来,路由器都是自己的设备,注定了路由器要配两张网卡,两种不同IP。路由器是整个子网的第一台主机,所以它的IP地址一般是子网号+1,所以IP地址被分为网络标识和主机标识。当某一个网络中新插入一个主机时,其网络标识必须一样,主机标识必须不一样,IP地址是被动态分配的。

路由器:具有路由的功能,但是现在的路由器不单单只有路由的功能,还可以构建子网。

在路由器的背面,提供了IP地址,可以在浏览器直接访问这个IP,更改路由器的属性。看到路由器有web功能。

手动管理子网内的IP非常麻烦,现在有一种技术叫DHCP,能够自动给子网内的新增主机节点分配IP地址,避免手动管理IP。一般的路由器都带有DHCP功能。

过去曾经提出一种划分网络号和主机号的方案,把IP地址划分为五类:

随着互联网的飞速发展,这种划分方法的局限性就显现出来。大多数组织都申请B类网络地址,导致B类地址很快就分配完了。比如,申请了一个B类网址,理论上一个子网内能允许6万5千多个主机,但是在实际中,一个子网内不会存在这么多情况,因此大量的IP地址被浪费了。

针对这种情况提出了新的划分方案,称为CIDR。

  • 引入一个额外的子网掩码来区分网络号和主机号;
  • 子网掩码也是一个32位的正整数,通常用一串"0"来结尾,以一串"1"开头;
  • 将IP地址和子网掩码进行"按位与"操作,得到的结果就是网络号;
  • 网络号和主机号的划分与这个IP地址是A类、B类、还是C类无关。

下面举几个例子,

1.IP地址是140.252.20.68,子网掩码是255.255.255.0,将这两者按位与,得到该IP地址的网络号140.252.20.0,所以子网地址的范围是140.252.20.0~140.252.20.255,主机地址全0(140.252.20.0)是网络号,主机地址全1(140.252.20.255)代表广播地址,所以能够真实作为主机IP的子网地址个数是256-2=254。这些子网掩码会在路由器中配置好。

2.每一个IP报文里会携带目的IP,子网掩码一般会配给路由器,同时还会给路由器配网络号,未来报文中的目的IP地址和路由器配置的子网掩码按位与,得到的结果如果和给路由器配置的网络号相等,说明该报文要去的网络和这个路由器是直连的,所以这个IP报文已经送到了目标网络的入口路由器处。比如IP地址是140.252.20.68,子网掩码是255.255.255.240,相与得到网络号140.252.20.64,其子网地址范围是140.252.20.64~140.252.20.79,计算过程如下:

但是40.252.20.64和140.252.20.79不用,所以这个子网可以接入一共有14台主机。可见,IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围;

IP地址和子网掩码还可以更简洁的方法,我们在书写的时候,子网掩码写在IP地址的后面,如140.252.20.68/28,表示子网掩码的前28个bit全为1,之后后4个bit位为0。

为什么要进行网段划分

经过精心的设计,对网段合理的划分,可以高效支持未来的报文路径查找,大大提高查找目标主机的效率

特殊的IP地址

  • 将IP地址中的主机地址全部设成0,就成了网络号,代表这个局域网;
  • 将IP地址中的主机地址全部设成1,就成了广播地址,用于给同一个链路中相互连接的所有主机发送数据包;
  • 127.*的IP地址用于本机环回测试,通常是127.0.0.1。

IP地址的数量限制

我们知道,IP地址(IPv4)是一个4字节32位的正整数。那么一共只有2的32次方个IP地址,大概是43亿个。而TCP/IP协议规定,每个主机都要有一个IP地址,这意味着最多有43亿台主机能接入网络吗?实际上,由于一些特殊IP地址的存在,可以IP地址数量远不够43亿个;此外,每一张网卡也需要配置一个或多个IP地址。

上面第二种网段划分方式在一定程度上缓解了IP地址不够用的问题,提高了利用率,减少了浪费,但是IP地址的绝对上限没有增加,还是不够用。可以通过以下3种方式来解决:

  1. 动态分配IP地址:只给接入网络的设备分配IP地址。因此,同一个MAC地址的设备,每次接入互联网的IP地址不一定是相同的。
  2. NAT技术。
  3. IPv6。IPv6并不是IPv4的简单升级,这两个协议互不相干,彼此互不兼容。IPv6用16字节128位来表示一个IP地址,目前并未普及。

私有IP地址和公有IP地址

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

  • 10.*前8位是网络号,共16777216哥地址;
  • 172.16.*到172.31.*,前12位是网络号,共1048576哥地址;
  • 192.168.*,前16位是网络号,共65536哥地址。

包含在这个范围中的,都称为私有IP,其余的则称为全局IP(或公网IP)。私网IP不能出现在公网中私有IP地址可以在不同的私网中重复。虽然存在公网,但是我们在上网时,都必须先接入指定一个内网中,我们所有人都在各自的内网中,没有人能接到公网里,只有运营商自己能接到公网里。


我们家里的路由器,一旦被组装好,就会形成一个内网环境,路由器能够构建子网。路由器也需要IP地址,就会去上面的私有IP地址中挑一个。然后家里的手机电脑就可以连上网络了,连上路由器后分配的IP地址是私有IP。路由器至少要级联两个网络,路由器连接的另一侧是运营商的子网环境,所以家用路由器要配两个IP地址,一个叫做LAN口IP(路由器自己构建的子网,子网IP),另一个叫做WAN口IP(对外连接到运营商的子网)。而运营商也有自己的LAN口IP和WAN口IP,在运营商看来,所有的路由器都构成了子网。从运营商自己的路由器之后,就开始接入到公网了,这个进入连接公网和内网的路由器叫做出入口路由器。抖音的服务器和运营商的服务器都在公网中,就可以通信了。网络世界=内网+公网构成网络是被各个国家的运营商精心设计过的


如上图所示,那如何把我们的报文通过网络发给抖音服务器,抖音服务器如何转发回来的呢?src:192.168.1.201,dst:122.77.241.3,我们自己的主机有自己的网络层,我们自己子网下的所有主机都知道自己的网络号是多少(主机IP地址&子网掩码),我要去的目标网络的网络号是122.77.241.0(目的IP地址&子网掩码),很显然,我要去的网络和我直连的网络不在同一个网段,就把报文交给家用路由器,家用路由器的WAN口号是10.1.1.0,也就是整个运营商构建的子网是10.1.1.0,而你要去的网络122.77.241.3,很显然也不是我们自己这个内网转发的,怎么办?只能把报文交给运营商的出入口路由器,这个路由器WAN口IP接的就是公网了,然后就把报文经过公网转到了抖音的服务器。任何主机都有能力知道和自己直连的网络号是多少。

那抖音服务器应答回来的时候,不就傻眼了吗?192.168.1.201是一个内网IP,内网中的IP地址可能会出现重复的,所以这种通信模式并不能正确地完成我们的通信。

那该怎么通信呢?src:192.168.1.201,dst:122.77.241.3,这个报文还是和上面一样,先交给家用路由器,因为私网IP地址不能出现在公网中,每经过家用路由器,都要将报文中的srcIP,替换为自己的WAN口IP,报文的IP就变成了src:10.1.1.2,dst:122.77.241.3,然后再交给出入口路由器,出入口路由器转发的时候,将srcIP转为该路由器的WAN口IP,src:122.77.241.4,dst:122.77.241.3,然后交给抖音服务器,抖音服务器以为在公网中的某一个设备在通信,然后把响应就可以把报文发回来给出入口路由器,接下来就是把报文内网转发。把这种在报文经过路由器转发的过程中不断进行源IP地址替换的工作,称之为NAT技术。只是进出内网的时候做替换,一旦进入公网后,就不需要替换了,因为公网之中所有主机是可以互相通信的。


路由

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

路由的过程,就是这样一跳一跳"问路"的过程。

举个例子,比如你第一次去上海,要去复旦大学,也没有导航,只能问路。遇到一个大爷,就问复旦大学在哪(排除被拒绝的情况),可能会得到以下几种回答:

1.大爷说,小伙子,你去坐206公交,到xxx下车,再坐36公交,就可以到了。

2.大爷说,小伙子,我也不太清楚啊,你去问一下火车站那个保洁大妈,她对方圆几十里比较熟。

3.大爷说,小伙子,你不用找了,我是复旦大学的保安,你现在到了。此时你立马问这个大爷,18号楼怎么走,大爷说,沿着路直走500m左手边(大爷帮你内网转发)。

IP数据包的传输过程也和问路一样。

  • 当IP数据包到达路由器时,路由器会先查看目的IP地址;
  • 路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器;
  • 依次反复,一直到达目标IP;、

每一个工作在网络中的设备,都会存在一个路由表(route指令查看),假设某主机上的网络接口配置和路由表如下:

这台主机有两个网络接口,一个网络接口连到192.168.10.0/24,另一个网络连到192.168.56.0,。Destination表示当前主机能找到哪些网络,目的网络地址;Gateway表示如果想去Destination,应该把报文交给哪一个IP的主机,下一跳地址,如果是*,表示要去的目标网络和我直连;Genmask是子网掩码,可以看到子网掩码不一样,这表明这台主机可以直接间接帮我们找到不同网段下的子网;Iface是收发数据的接口;Flag中的U标志表示此条目有效,G标志表示此条目的下一条是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发,Destination是default,表明这是缺省路由。

当该路由器拿到报文后,拿目的IP地址和子网掩码相与,去看Destination里有没有匹配的,如果没有匹配的,只能去缺省路由了。然后把报文通过eth0接口把报文发出去。

转发过程例1:如果要发送的数据包的目的地址是192.168.56.3

  • 跟第一行的子网掩码做与运算得到192.168.56.0,和第二行的目的网络地址一样,所以从eth1接口发送出去;
  • 由于192.168.56.0/24正是与eth1接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发;

转发过程例2:如果要发送的数据包的目的地址是202.10.1.2

  • 依次和路由表前几项进行对比,发现都不匹配;
  • 按缺省路由条目,从eth0接口发出去,发往192.168.10.1路由器;
  • 由192.168.10.1路由器根据她的路由表决定下一跳地址。

最后再来谈一下IP报头中16位标识、3位标志、13位片偏移。

上层交给数据链路层的报文,数据链路层也要添加自己的报头,数据链层层规定其有效载荷的长度是有上限的,一般不能超过1500字节,称为MTU(最大传输单元),如果超过了MTU,数据链路层就不提供链路转发。网络层一看数据链路层的态度那么强硬,网络层又颤颤巍巍看了传输层,就渴望地对传输层说你给我的报文能不能小一点,因为报文是否超过1500字节是由你传输层决定,但如果传输层的态度也很强硬,传输层就给网络层传输2000字节,网络层也很无语,上下两层都很强硬,只能自己想办法了。网络层只能分片 转发了,把传输层传来的2000字节分成两个1000字节,分批传给数据链路层。网络层即使虽然分片了,但是传输层和数据链路层都不知道也不关心,但是接收方收的时候,不能收到两个1000字节的,而必须是完整2000字节的,所以对方网络层必须要做组装,将两个1000字节组装好再向上交付。

经过这一点理解,我们要知道这几点:

  1. 在网络世界里,只有IP报文!只有双方主机才能知道这是TCP/UDP报文。
  2. 假设要发1个IP报文,后来分片成10个IP报文发出去,但是有1个报文丢了,所以对方网络层就不能把9个报文交给上层传输层。分片中,有一片报文丢失,表示整个报文丢失!不给传输层交付,传输层也就收不到,收不到也就不会有应答,发送方就会自动超时,就只能进行重传了。

如果过多分片,就会增加丢包概率。分片组装这不是也不应该是网络转发的主流!丢包对于上层的影响是相同的,只不过对于TCP由丢包重传机制,UDP没有。

由于丢包后传输层就要重传,所以,为了尽可能避免丢包,就尽量避免分片,所以网络层最多能接受传输层1480个字节,传输层的报头是20个自己,那传输层从发送缓冲区一次读取的字节最多是1460字节,这也就是TCP滑动窗口中的内容不能一次打包全部发送,而是要分段发送的原因,最本质的就是因为数据链路层底层有MTU的要求!

接收方收到的报文有分片的,也有没分片的。我们先来看一下如何组装:

1.如何区分我收到的报文是分片了呢?

对于16位标识,不同报文的标识是不一样的,而一个报文的不同分片,标识必须相同。

对于3位标志字段,第一位是保留的,第二位为1表示禁止分片,如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示"更多分片",如果分片了,最后一个分片置为0,其它为1,类似于一个结束标记。

对于13位片偏移,是分片相对于原始IP报文(报文数据)开始处的偏移,其实就是表示当前分片在原报文中处于哪个位置。实际偏移的字节数是这个值的8倍(实际偏移的字节数右移3位得到13位片偏移)。因此,除最后一个报文之外,其他报文的长度必须是8的整数倍。

那如何区分收到的报文是不是分片了呢?首先,我收到的报文要么是第一片,要么是中间片,要么是最后一片。如果是第一片,"更多分片"就是1,且片偏移是0;如果是中间片,"更多分片"就是1,且片偏移>0;如果是"最后一片",那更多分片一定是0,且片偏移一定大于0。

因此,if(更多分片 == 1 || 片偏移>0){分片了}。

那如果没有分片呢怎么识别,更多分片一定是0&&片偏移是0,就是没分片。

**那如何保证我们把分片收全了呢?**那就先想想如果没有收全,会发生什么。如果没有收到第一片,那就是没有偏移为0的。如果没有收到最后一片,那就会没有收到更多分片为0的。然后,为了判断是否没收到中间片,可以将所有分片按照片偏移进行升序排序!拿着第一个分片的偏移量+自己长度,就应该是下一个分片偏移量的值,如果发现不是,就甄别出来中间是哪一个分片丢了。如果遍历完到最后一个分片,发现所有的都符合当前分片的偏移量+自己长度,就应该是下一个分片偏移量的值,这就是收全了。

如何组装?对收到的分片,边收边排序,按照偏移量头插,只要收全了,自然就组装好了。

相关推荐
A小辣椒14 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒18 小时前
TShark:基础知识
linux
AlfredZhao20 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux