Linux网络-网络层IP协议、数据链路层以太网协议、ARP协议、ICMP协议和NAT技术


前言

上一章我们已经学习了传输层的TCP协议和UDP协议,本章我们来讲传输层的下一层,网络层IP协议。


一、IP协议

对于IP,我们之前也有过一些简单的表述,我们说要在全网中找到唯一一台主机就需要目标IP地址。

这次我们主要对IP进行一个更加深入的认识。

IP报头解析

在这里插入图片描述
IP报文与TCP报文格式有点相似,他们的报头都是固定20字节+选项长度,最后都是它们自己的有效载荷。

4位版本

对于IPv4而言,它的版本就是4,所以这里的四位版本就是4。
那么IPv6呢? IPv6可以说基本与IPv4在结构上完全不相干,所以这里的4位版本与IPv6没有任何关系。

4位首部长度

与TCP的4位首部长度一样,TCP报头与IP报头都是20字节+选项字节长度,所以这里也是一样,4个bit位能代表0 - 15 ,加上以4字节为单位的话,就是0 - 60字节。

16位总长度

16位总长度代表的就是整个报文的长度,16位bit可以代表2^16 - 1 = 65535个字节。 所以刚好,通过16位总长度 - 4位首部长度就可以得到有效数据载荷的长度。

8位生存时间

TTL(Time To Live)代表一个IP报文最多可以经过多少次路由器的传递,TTL刚发出时一般为64,之后每经过一个路由器,TTL - 1, 如果等TTL减到0还未到达目标主机,该报文则被舍弃。

这样设计的原因是因为我们在查找目标主机的时候,并不是每次都能找到目标主机的,有时候会因为网络或者对方主机出现问题,导致报文一直在各个路由器流窜,如果不进行一定时间内的销毁,那么这些流窜的报文将会持续存在,且耗费资源。所以就有了TTL来控制报文的生存时间。

8位协议

这8位协议存储的是上层协议的类型,目标主机在拿到IP报文时,就可以通过报头中的8位协议找到解包之后的有效载荷应该交给哪个协议,是交给UDP协议还是TCP协议。

当然,在封装的时候也是一样,会根据上层的哪个协议交付给IP协议来填写8位协议。

16位首部校验和

用来校验首部数据是否有问题,这里不做细讲。

32位源IP地址和32位目标IP地址

这个已经很明显了,不做过多解释了。

我们的32位IP地址换算下来一共可以有42亿多的IP地址。相当于说全网可以代表42亿个入网设备,但是现如今已经不同于20多年前,如今的入网设备已经不止42亿台设备了,所以现如今就需要有解决方案,IPv6也是一种解决方案。

网段划分

不过我们先来讲讲网段划分的概念,IP地址分为两个部分, 网络号和主机号

子网-局域网

以我们的路由器为例,我们连接我们路由器的网络,其实就是连接上了路由器创建的一个子网,我们也称这个子网为局域网。

在这里插入图片描述
以上图为例,192.168.128这里就可以被理解为网络号 ,一台主机的主机号为10,所以它的IP地址就是192.168.128.10,另一台主机的主机号为11,那么它的IP地址就是192.168.128.11。

不同的子网其实就是把网络号相同的主机放到一起。


过去曾经提出一种划分网络号和主机号的方案, 把所有IP地址分为五类, 如下图所示(该图出自[TCPIP])。
在这里插入图片描述

  • 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

比如说A类, 如果你可以申请一个1.开头的网络IP地址,那么你申请的这个网络理论上就可以连接2^24台主机。

所以缺点很明显,申请这样一个A类或者B类的网络,即使是一个组织,企业,想要让一个子网连接这么多台主机是很难的(就需要有网络运营商)。
所以这就势必会造成许多IP地址是荒废的。 更何况现在的如今互联网时代,42亿个IP地址对应每一台入网设备的话,都根本不够分,你竟然还浪费。

所以针对这一问题,我们就提出了新的划分方案,称为CIDR(Classless Interdomain Routing)。
引入一个额外的子网掩码(subnet mask)来区分网络号和主机号。

子网掩码

子网掩码也是一个32位的正整数. 通常用一串 “0” 来结尾,将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号。

由子网掩码按位与出来的网络号和主机号的划分与这个IP地址是A类、B类还是C类无关。

IP 地址 & 子网掩码就能得出网络号,所以只要子网掩码的 1 更少,网络范围就更大, 子网能连接的设备就越多。

在这里插入图片描述

再比如说我现在电脑的IP地址
在这里插入图片描述
其中网络号就是192.168.0 , 主机号是102.
连入我这一子网的主机的IP范围就是192.168.0 ~ 192.168.255。

这仅仅是我这个路由器的子网掩码,而我路由器需要连接的是运营商的路由器,所以我的路由器也存在于运营商路由器的子网当中,它的子网地址范围一定会比我大很多,因为肯定不止连接我家一个路由器,需要连接到万户的路由器。

所以运营商的路由器的子网掩码的全1bit位就会更少,我们的设备包括私人路由器也是处于运营商路由器的子网范围当中。

引入子网掩码以后,就可以将网络号划分地更细,更好的利用我们的IP地址。

特殊的IP地址

将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网。

将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包。

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

公网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);

意思就是私网IP地址是无法直接连上Internet的。 而我们最常见使用的最多的192.168.x.x,就是私网IP地址!

在这里插入图片描述
且我们这些私网IP地址,在不同的局域网子网之下,是可以重复的!这也大大提高了IP地址的利用率。

那我们这些私网无法直接连入公网,我们是怎么访问别人服务器资源的呢? 答案是通过运营商!


运营商

我们虽然经常会吐槽运营商这不好那不好,但是实际上运营商对于我国的互联网发展是起到了十分重要的作用的。

因为想要维护我国这样如此庞大的网络,是需要许多网络服务器的,这些服务器成本是十分巨大的,而且想要让家家户户都连上你的网络,需要不少的时间。 所以没有企业能够负担,这就需要国企来承担这一责任,于是就有了我们国内的运营商! 是这些运营商在我们需要联网装路由器的时候来派基层人员来给我们安装宽带、网络,当然这也是要收费的。


我们的数据先通过自家路由器,然后通过调制调节器(光猫)将数字信号转化为光纤信号到运营商的路由器,再由运营商的路由器连接到公网上,再将报文从公网上一步一步转发给目标主机。

这个转发的过程,我们称为路由

路由

路由这里需要涉及到网络层和数据链路层,我们先来讲讲网络层上是怎样运作的。

要将报文数据进行转发,首先要判断这个报文数据的目的主机是不是在报文当前所在主机所连接的子网内,这是通过路由表来判断的。

路由表

需要注意的是,路由表可不仅仅只是在路由器才有的,我们的电脑、手机、云服务器上也有路由表。

在Linux的命令行中输入 route

可以查看当前主机的路由表
在这里插入图片描述

  • Destination是目标网络地址,一般是这台主机所连接的子网网络地址,可以看到有个default,这是默认路由地址,我们等会会讲。

  • Gateway是下一跳地址。 Iface是发送接口,因为我的这个服务器只处于一个路由器的内网当中,所以也就只有一个发送接口。

  • Genmask就是子网掩码。

  • Flags中的U标志表示此条目有效(可以禁用某些 条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。

假设有一个目标IP为42.1.1.1的报文数据到了我这台主机,我首先要判断它的目标IP地址是不是处于我的这个子网内,判断方法就是将 (目标IP地址 & 子网掩码) == Destination
在这里插入图片描述

(42.1.1.1 & 255.255.252.0 = 42.1.0.0) != 10.0.4.0
所以这个报文就不是发给网络号为10.0.4.0的子网,接着就继续找这台主机连接的另一个子网是否匹配。

如果没有找遍了路由表还是没找到,这个时候default 默认路由地址就有作用了,default一般代表该网段的另一台主机,它就会走default路线将这个报文通过eth0这个接口发给另外一台主机,另外一台主机再重复上面的这个操作,从一个路由器跳到另一台相连的路由器,这就会越来越接近目标IP主机。

又需要注意的是,路由表只是用来判断该报文目标IP是否处在当前主机所连接的子网,至于下面跳转路由器的过程,涉及到MAC帧,MAC帧我们紧接着会讲!

在这里插入图片描述


重复若干上面查找路由表的操作和跳路由器的动作之后,当这个报文终于找到了目标IP所在的网段,又应该怎样进行下一步呢?而且这个跳的过程又是怎样进行的呢?

这就又需要涉及到数据链路层和MAC帧。

数据链路层

所谓的数据链路层,也就是我们的网卡驱动,物理层,之前我们最初学习网络基础的时候也微微提到过。 MAC地址是用于在局域网中通信的,当上面的那个千里迢迢才找到目标IP所在的子网的报文数据,最后到达了这个子网后,就是需要在局域网中转发这个数据!

局域网间主机的通信就是靠MAC地址来查找目标主机的。

MAC帧格式

我们以以太网为例,数据链路层不同协议的MAC帧格式都差不多。
在这里插入图片描述

  • 6字节目的地址就是 目标主机的MAC地址。
  • 6字节源地址就是 发送主机的MAC地址。
  • 2字节类型就是分辨该报文MAC帧报文数据类型,有可能会是携带了IP数据报头的数据,也有可能是APR请求/应答、也有可能是RARP请求/应答。
    对于ARP和RARP我们等会还会详细讲解。
  • CRC是CRC校验码,用于保证数据帧的完整性。

局域网通信原理

当局域网的一台主机想向另一台处在同一局域网的主机发送数据,首先要从应用层不断将数据向下经过传输层,网络层,数据链路层的封装,其中在数据链路层会封装MAC帧报头。然后经过数据链路层的网卡设备向局域网发送报文数据,这个报文数据是会被所有处于局域网的主机都接收的,不过所有主机的链路层会根据MAC帧报头中的目的MAC地址来判断是否是发给它的报文数据,如果不是则丢弃。 是的话则一路经由网络协议栈向上交付解包。

局域网数据碰撞

原则上,局域网同一时间只能同时存在一个报文数据,如果同一时间存在多个报文数据,则会造成数据碰撞,导致数据出现问题,最后数据会被所有主机舍弃,为了减少数据碰撞,就需要设计防碰撞算法来尽量减少数据碰撞的发生概率。

不过光靠防碰撞算法也是不够的,在一台子网连接的主机数量达到一定程度时,数据碰撞还是会经常发生,例如说学校的校园网,当其他宿舍同学去上课时,你的网络就很好,他们下课时就会很卡,这不仅仅是网络带宽的问题,也有可能是同一子网内连接的主机太多发生了数据碰撞。

还有一种设备——交换机,也能减少数据碰撞的发生概率,叫交换机可以分割碰撞域,可以将过多的主机的局域网分割开来。


MTU

MTU(Maximum Transmission Unit)是不同的数据链路对应的物理层所能发到局域网中最大的有效载荷长度, 报文长度 = MAC帧报头长度 + 有效载荷/IP数据报长度(不能超过MTU)
在这里插入图片描述

在这里插入图片描述

  • 以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位;
  • 最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
  • 如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation);
  • 不同的数据链路层标准的MTU是不同的;
分片(网络层IP协议)

以以太网为例,
因为我们的数据链路层以太网帧中的数据长度最多只能携带1500字节,那么网络层给数据链路层传的报文就不能超过1500字节,可是网络层也是从传输层拿的数据,传输层像UDP协议他就是硬塞给网络层一个特别长的报文数据,那么网络层IP协议就要考虑到数据链路层的MTU,就必须要做到分片,将过长报文分成多个部分。

在这里插入图片描述
现在讲了将过长的IP报文分片的过程,那么怎么将这些被分片的IP报文拼装起来呢?

因为这些报文都携带了MAC帧,所以也就能找到目标主机,目标主机也需要在网络层将这些分片的报文拼装起来,但是这些拼装的报文,谁是头谁是尾,该如何分辨?

可别忘了我们我们的IP协议报头还有一行没讲呢。

在这里插入图片描述
16位标识(id): 唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的。

3位标志字段: 第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文。第三位表示"更多分片", 如果分片了的话,最后一个分片置为1, 其他是0。类似于一个结束标记。
所以根据标志字段的最后一位我们可以知道该分片报文是不是最后一个分片。

13位分片偏移(framegament offset): 是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。

我们再以上面那个被分片的IP报文为例

在这里插入图片描述


虽然网络层有了分片可以保证我们的数据链路层能够发送MTU的数据,但是我们还是要避免分片,因为分太多片势必也会提高局域网中数据碰撞的概率,造成的直接后果就是分片的数据丢失。就又需要数据链路层进行超时重传,是的,数据链路层也有超时重传机制

但是IP层和数据链路层都没有办法控制报文数据有效载荷的大小,我们就只能依靠传输层来进一步约束它的报文数据长度。
再联系TCP协议的滑动窗口,为什么我们的滑动窗口当时在写的时候里面是一个部分一个部分,这就是因为它也要考虑到MTU,而滑动窗口里那一个部分一个部分的长度,我们称之为MSS(Maximum Segment Size)最大报文长度

如果说我们这里的数据链路层的物理层的MTU是1500,那么我们的MSS可以这样计算 MSS = 1500 - IP报头(20字节) = 1480

又由于我们通信的两台主机的MTU可能是不一样的,所以我们在TCP协议的三次握手时也会同时互相发送各自的MSS长度(选项当中),再协商使用两台主机的最小MSS来制定双方的滑动窗口的MSS。


可是,上面还有一个十分重要的部分我们没讲,那就是这个报文数据是如何在两个主机之间“跳”的,这个报文数据到达了目标IP地址所在的入口路由器,我们又怎么从局域网中找到该目标主机?局域网是通过MAC地址来通信的,而我们的报文数据只有IP地址。

所以又有IP地址转MAC地址,这种转换方式又是基于ARP协议。

ARP协议

ARP不仅仅是一个数据链路层协议,它是位于以太网/令牌环协议之上,网络层IP协议之下,是一个介于数据链路层和网络层之间的协议;

ARP协议的作用

它建立了一个ARP协议建立了主机 IP地址 和 MAC地址 的映射关系。
所以,两台主机想要进行局域网通信,就首先要获取一方的MAC地址,就需要先发送ARP报文。
在这里插入图片描述

  • 源主机发出ARP请求,询问“IP地址是192.168.0.1的主机的硬件地址是多少”, 并将这个请求广播到本地网段(以太网帧首部的目的以太网地址填FF:FF:FF:FF:FF:FF表示广播);
  • 目的主机接收到广播的ARP请求,发现其中的IP地址与本机相符,则发送一个ARP应答数据包给源主机,将自己的硬件地址填写在应答包中。 如果非目标主机收到这个广播的ARP请求,则直接在ARP协议层解析并丢弃。
  • 每台主机都维护一个ARP缓存表,可以用arp -a命令查看。缓存表中的表项有过期时间(一般为20分钟),如果20分钟内没有再次使用某个表项,则该表项失效,下次还要发ARP请求来获得目的主机的硬件地址

ARP数据报的格式

在这里插入图片描述
以太网首部我们就不再重复了,需要注意的是以太网首部的帧类型会因为封装的数据是ARP数据,这里的帧类型是0806。
在这里插入图片描述

  • 硬件类型指链路层网络类型,1为以太网。
  • 协议类型指你的网络层协议地址类型,0x0800为IP地址。
  • 硬件地址长度对于以太网地址为6字节。
  • 协议地址长度对于和IP地址为4字节。
  • op比较重要,用于分辨是ARP请求还是应答。请求为1,应答为2。
  • 剩下的发送端以太网地址、发送端IP地址、目的以太网地址、目的IP地址无需多谈。

环境模拟

现在我们来模拟一下ARP请求应答的环境来让我们更好的认识ARP请求与应答的过程。
在这里插入图片描述

RARP请求/应答

RARP与ARP相反,ARP是用IP地址来找询问对应主机的MAC地址,RARP是通过MAC地址来询问对应主机的IP地址。 这里对RARP不做细讲。

DNS(Domain Name System)

域名解析系统

例如我们输入www.baidu,com 或者baidu.com的时候,其实本质也是通过访问IP地址的方式来访问百度服务器的资源,但是这里如何将域名转化为IP地址,就需要访问DNS系统,将域名交给DNS服务器,再由DNS服务器给我们返回对应的IP地址。
如果本地由对应的DNS缓存就不必访问访问DNS系统了。

ICMP协议

ICMP协议是一个 网络层协议。 ICMP是位于IP协议之下,网络层之内的一个协议。
一个新搭建好的网络, 往往需要先进行一个简单的测试, 来验证网络是否畅通; 但是IP协议并不提供可靠传输. 如果丢包了, IP协议并不能通知传输层是否丢包以及丢包的原因。

ICMP正是提供这种功能的协议,ICMP主要功能包括:

  • 确认IP包是否成功到达目标地址。
  • 通知在发送过程中IP包被丢弃的原因。
  • ICMP也是基于IP协议工作的. 但是它并不是传输层的功能, 因此人们仍然把它归结为网络层协议。
  • ICMP只能搭配IPv4使用. 如果是IPv6的情况下, 需要是用ICMPv6。

例如我们的ping命令
在这里插入图片描述
ping命令基于ICMP, 是在网络层. 而端口号, 是传输层的内容. 在ICMP中根本就不关注端口号这样的信息。
所以以后面试问到ping是什么端口不要掉坑里去了。

traceroute命令

在这里插入图片描述
traceroute命令也是基于ICMP协议,它其实就是通过改变IP报头中的TTL来追踪我们访问一个目标IP所需要经过的路由地址。 因为我们的路由在因TTL为0时丢弃报文的同时也会给我们返回一个ICMP报文回来。

NAT技术

以上的内容,我们都清楚的讲解了一个处于内网中的主机向一个处于公网中的服务器发送数据请求的整个过程。 可是,既然收到了一个请求,我们的公网服务器就需要作出对应的应答,我们的公网服务器又如何做到回去找到处于内网的主机呢?

在这里插入图片描述
在内网向公网发出的数据每经过一个仍处于内网的子网的路由器时,这个路由器都需要有对应的NAT转换表,并在这个转换表插入对应的私网IP地址端口号的映射,并将IP报头中的源内网IP地址换成新的WAN口IP地址。TCP/UDP报头中的源端口号换成新的不与其他转换表中重复的端口号。

所以当公网的应答回到该路由器时,它会查找NAT转换表,并通过转换表将IP报头的目标IP地址和TCP/UDP报头的目标端口号重新换成转换表中对应的内网IP地址和端口号。 这样就实现了公网的应答传到内网中。

像我国的网络环境,我们家里一个家用路由器,然后家用路由器还要连接到运营商的路由器,而且这个运营商的路由器还不一定直接是连到公网,可能还得又经过一个运营商路由器。 所以我们用电脑向公网发起请求,这个请求报文是会有多个NAT转换表的映射的,会有多个替换源IP和端口号的过程。

通过NAT技术,可以有效缓解目前IP地址不足的问题。

NAT技术的缺陷

由于NAT依赖这个转换表, 所以有诸多限制:
无法从NAT外部向内部服务器建立连接;
转换表的生成和销毁都需要额外开销;
通信过程中一旦NAT设备异常, 即使存在热备, 所有的TCP连接也都会断开;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风君子吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值