当一个报文需要从一个主机转发到另一个主机的时候,表面上是 IP 报文的跨网络转发,但也并不是直接就将数据报转发到对应的主机了,而是从网络层更下面的数据链路层一跳一跳的转发到下一个链路层,数据链路层实现的是到达短距离目的地址的通信,而 IP 实现的是到达最终目标地址的通信。
本篇开始将详细的介绍有关数据链路层的相关知识,以及在链路层中的 ARP 协议。其中主要涉及的知识有:以太网和对应的帧格式、MAC 地址、MTU、交换机以及 ARP 协议。
目录
以太网/以太网帧格式
MAC地址
MTU
MTU对传输层的影响
交换机
ARP协议
以太网/以太网帧格式
常说的以太网其实并不是一种具体的网络,而是一种技术标准,既包含了数据链路层内容,也包含了一些物理层的东西,比如以太网规定了网络拓扑结构,访问控制方式,传输速率等等。同时,以太网还是当前应用最广泛的局域网技术,和以太网并列的还有令牌环网,无线 LAN 等等。
以太网帧格式如下:
如上所示的以太网数据帧格式,以上的目的地址、源地址、类型和 CRC 字段都是定长的,所以当我们拿到一个以太网帧的时候,只需要截取前 14 个字节和后 4 个字节就可以将数据报文向上交付了。但是在交付之前也需要查看对应的以太网帧类型,IP 数据报类型的数据直接向上交付,而对于 ARP 、RARP 报文则只需要交给对应的链路层协议即可。
MAC地址
MAC 地址是用来在链路数据层中识别相连结点的地址,长度为 6 字节 48bit,使用 16 进制数字加上冒号的形式来表示,如:05:00:27:fb:19。
MAC 地址在网卡出场时就已经确定了,不能被修改,所以对于我们的 MAC 地址通常是唯一的(虚拟机中的 mac 地址不是真实的 mac 地址, 可能会冲突; 也有些网卡支持用户配置 mac 地址)。使用 MAC 地址进行局域网通信的流程如下:
当 A 主机拟定了一个以太网帧,目的地址是 E 主机,A 主机就会将自己的以太网帧发送在局域网内,只要是在这局域网内的所有主机,都可以收到这个帧,但是当接收这个帧之后,在链路层会发现该帧的目的 MAC 地址并不是本主机,就会将该帧给丢弃,只有当目的 MAC 地址刚好等于该主机的时候,才会接收。但是需要注意的是,在一个局域网内,一个时刻只允许一台主机发送MAC 帧,要不然会导致帧碰撞,丢包(丢包之后会进行碰撞检测,检测到当前没有数据帧发送的时候就会重传,若一直重传失败就会像上层报告传输失败)。
MTU
在数据链路层中发送的数据越长就会导致该数据帧占用链路的时间就会越长,占用的时间越长发送帧碰撞的概率越高,所以链路层对于发送数据报的最大长度进行限制,就出现了 MTU(最大传输单元),相当于发快递时对包裹尺寸进行限制。
以太网帧中的数据长度规定最小 46 字节,最大 1500 字节,ARP/RARP 数据报的长度不够 46 字节,需要在后面填补充位。
不同链路层标准的 MTU 是不同的,但是通常最大是 1500 字节。
同时 MTU 还会对上层网络层产生影响,因为 MTU 规定数据长度最大只能有 1500 字节,然而在网络层允许的最大长度为 65535 字节,所以这就会迫使超长的数据在网络层被分片(关于分片的具体细节,可看这篇文章:网络层IP协议-CSDN博客)。
MTU对传输层的影响
MTU 规定了在链路层中最大发送报文的长度,然而在数据链路层中的数据结构却可以远远大于 MTU 规定的长度,假若我们将其在网络层分片,某个分片报文的丢失也会导致这个报文的失效,所以分片无疑会增加丢包的概率,所以 MTU 促使从传输层传下来的数据报长度也尽量的小。
MTU 对 UDP 协议的影响:UDP 协议是没有重传机制的传输层协议,一旦 UDP 数据在网络层中被分片,其中某个分片数据报丢失就都丢失了,且没有重传机制,就是真正的丢包了,所以对于 UDP 数据报应该尽量控制在 1472 字节(1500 - 20 - 8)。
MTU 对 TCP 协议的影响:TCP 的单个数据报的最大消息长度被我们称为 MSS(max segment size),TCP 在建立通信的时候就会协商该 MSS 的值(双方在发送 SYN 的时候就会在 TCP 首部写入自己能支持的 MSS 的值,双方选取其中的最小值作为最终的 MSS,MSS 的值就是在 TCP 首部的 40 字节变长选项中),在最理想的情况下,MSS 的值正好是在 IP 不会被分片处理的最大长度
交换机
在数据链路层中存在一些叫做交换机的设备,如下:
如上所示,交换机所处的位置是在链路层的链路中,将两个链路给分隔开,同时使用 i0、i1 接口连接两个链路。一个刚接入链路层的交换机中并没有任何的接口信息,当局域网中主机 A 想要发送帧给主机 E 的时候,交换机也会收到该数据帧,然后将其转发到另一个链路,但是此时交换机会记录下 A 主机来自 i0 所在的链路,当主机 E 想要发送消息给主机 A 的时候,交换机检测到主机 A 在 i0 对应的局域网内,就会将其转发到左边的局域网内。
只要是局域网中发送的数据帧不管是跨局域网发送还是局域网发送,被交换机接收后都会记录下发送主机位于哪个局域网,这样很快交换机就会记录下两侧局域网的所有主机位于哪个局域网。当收集所有主机之后,在一次接收到对应的数据帧,若交换机检测到目的主机在另一个局域网则会转发,不在则不会转发。所以交换机的作用是:把一个大的碰撞域分隔成多个小的碰撞域,在相同时刻的不同碰撞域之间的主机就可以同时发送数据帧了。
ARP协议
当我们需要进行远端发送数据的时候,知道目的主机的 IP 地址,但是在路由转发的时候,每一跳的目的 MAC 地址都会随之改变,并且只有当目的 MAC 地址和收到消息的主机的 MAC 地址相同的时候才会将数据报向上交付,所以如果我们不知道目的主机的 MAC 地址就根本不能将数据传输到对应的目主机,所以我们还需要一种将 IP 地址转成 MAC 地址的能力:每走入一个局域网,都通过 IP 来获取对应的 MAC 地址,才能逐步的走到目的主机。
具有以上功能的协议就是我们的 ARP 协议。
ARP 协议位于数据链路层,但是和 MAC 帧层并不是并列在数据链路层的,而是处于 MAC 帧的上面。ARP 协议的功能为:建立主机 IP 地址和 MAC 地址的映射关系。ARP 协议的由来:
在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,但是却不知道目的主机的硬件地址;
数据报首先是被网卡接收到再去处理上层协议,若接收的数据包的硬件地址和本机不符,则直接丢弃。
所以在通讯前必须获得目的主机的硬件MAC地址
ARP 协议的工作流程如下图:
注:上图中从路由器 R 构建的 ARP 请求报文中 MAC 帧层的类型字段应该为 0806,目的 MAC 地址应该为 macE。 RAP 为地址解析协议,将 IP 报文转化为 MAC 地址,RARP 为逆地址解析协议,将 MAC 地址转化为 IP 地址。
如上图所示,当路由器想给主机 E 发送消息的时候,由于不知道主机 E 的 MAC 地址,所以构建了对应的 ARP 请求报文(先是在 ARP 层构建出对应的 ARP 请求,其中需要填上主机 E 的目的 IP 地址,以及将目的 MAC 地址设置成全 F(广播地址,所有主机都会收到),然后将 ARP 请求向下传输,然后在封装对应的源 MAC 地址和目的 MAC 地址以及类型),然后向子网内发送,在子网中的所有主机都会收到该报文,并且将 MAC 帧层的数据解包,向上传输到 ARP 层,当发现目的 IP 地址不是本主机的时候就会将该报文丢弃;当发现目的 IP 地址是本主机的时候,就会构建出对应的 ARP 应答报文,在 ARP 层将目的 IP 和 目的 MAC 以及源 IP 和源 MAC 地址封装起来,在 MAC 帧层也封装起来,然后发回到路由器 R,路由器 R 就知道了主机 E 的 MAC 地址。
链路层中的 ARP 请求报文和 ARP 应答报文的类型字段都是 0806,那么我们的主机如何区分发送过来的报文是 ARP 请求报文还是 ARP 应答报文呢?如上图所示,在 ARP 报文字段中对应的 oper 标记着这个报文是请求还是应答报文。当一个主机收到 ARP 报文之后,第一个看的字段便是 oper(识别是应答还是请求),然后看对应的目的 IP 地址是不是本主机。
我们通过 ARP 请求获取对应的 MAC 地址的过程还是比较繁琐的,所以当我们的获取到一个主机的 MAC 地址之后,我们的主机会将该 MAC 地址给暂时缓存起来,可以使用指令 arp -a 来查看,如下:
ARP 数据报的格式如下:
在以太网首部和 ARP 请求/应答中,MAC 地址会各出现一次,这样的出现并不是重复的,因为在 mac 帧层会剥离掉一层,并且看不到之后的数据,所以这样的重复是很有必要的。
硬件类型指的是链路层网络类型,1 表示以太网
协议类型指要转换的地址类型,0x0800 为 IP 地址
硬件地址长度对于以太网地址为 6 字节
协议地址长度对于和 IP 地址为 4 字节
op 字段为 1 表示 ARP 请求,op 字段为 2 表示 ARP 应答