Linux 网络:数据链路层

前言

在前面的学习中,我们已经了解了 IP 协议、路由转发以及 TCP 的基本工作原理。现在,我们需要继续向下探索:当网络层已经确定了数据应该交给谁时,数据究竟是如何通过网卡发送出去的?

假设主机 A 想要与主机 E 通信,网络层通过路由表确定了下一跳 IP 地址,但网卡实际发送以太网帧时,需要填写目的 MAC 地址。这个 MAC 地址从哪里来?数据帧发送到局域网后,其他主机为什么也能收到?交换机又是如何减少网络中的冲突的?

这些问题都与数据链路层密切相关。

本文将围绕以太网和 ARP 协议展开,依次介绍数据链路层的基本职责、以太网帧格式、MTU 限制、局域网通信原理、交换机的工作机制,最后通过 ARP 协议补齐从下一跳 IP 地址到下一跳 MAC 地址的整个通信过程。

一、数据链路层的作用:让 IP 报文能够在当前链路上传输

1. 网络从局域网发展到广域网

网络技术的发展并不是一开始就有一个统一的全球网络。

早期,不同机构分别研究和建设自己的网络,形成了不同的局域网技术。随着网络不断发展,这些局部网络逐渐互联,最终形成了规模庞大的互联网。

在这个过程中,以太网、令牌环和无线局域网等技术承担了不同的局部通信任务。

问题也随之出现:不同网络的底层通信方式不一样,如何让它们互相通信?

答案是 IP 协议。

IP 协议负责网络层的寻址与路由转发,使上层不必直接处理每种底层网络的具体差异。例如,电脑可以通过有线以太网接入网络,手机可以通过 Wi-Fi 接入网络,只要它们能够通过 IP 网络互通,上层应用就可以使用统一的套接字编程接口进行通信。

2. IP 地址与 MAC 地址,分别解决什么问题?

IP 地址和 MAC 地址都可以标识通信中的对象,但它们的作用范围不同。

  • **IP 地址:**用于网络层寻址,帮助数据找到目标网络和目标主机。

  • **MAC 地址:**用于数据链路层寻址,帮助数据帧在当前链路上交付给下一跳设备。

可以用下面的结构理解两者的关系:

例如,主机 A 要跨网络访问主机 E:

复制代码
主机 A                 路由器                    主机 E
  |                       |                         |
  |--- MAC 帧 ----------->|                         |
  |                       |--- 新 MAC 帧 ---------->|
  |                       |                         |
  |  第一个链路            |      第二个链路          |

路由器收到数据后,会根据 IP 报文中的目的 IP 地址进行路由转发。转发时,它会去掉接收链路上的数据链路层封装,再根据下一跳重新封装。

因此:

  • 从网络层来看,源 IP 和目的 IP 通常保持不变(不考虑 NAT 等会修改地址的情况)。

  • 从数据链路层来看,每经过一个路由器,源 MAC 和目的 MAC 通常都会根据下一段链路重新确定。

  • 不同链路还可能使用不同的数据链路层协议。

这就是 IP 协议能够屏蔽底层网络差异的重要原因。

3. 数据链路层的基本职责

数据链路层主要负责当前链路上的帧封装、地址识别、差错检测以及向上层交付数据。

以太网是最常见的数据链路层技术之一。下面我们就从以太网帧的具体格式开始分析。

二、以太网帧格式:数据链路层如何封装数据

1. 什么是 MAC 地址?

每张网络接口通常都有一个 MAC 地址。MAC 是 Media Access Control 的缩写,MAC 地址通常为 48 位,也就是 6 字节。

例如:

复制代码
3C:52:82:AB:CD:EF

每两个十六进制数字表示一个字节,一共六组。

在 Windows 中,可以使用下面的命令查看网卡信息:

复制代码
ipconfig /all

在 Linux 中,可以使用:

复制代码
ip link

或者在安装了 ifconfig 的系统中使用:

复制代码
ifconfig -a

需要注意,MAC 地址通常用于当前链路上的设备识别。即使一个 MAC 地址在全球范围内具有唯一性,也不意味着它能像 IP 地址一样用于全球路由转发。

核心区别:IP 地址负责网络层寻址,MAC 地址负责当前链路上的帧交付。

2. 以太网帧的整体结构

网络层将 IP 报文交给数据链路层后,以太网需要为它添加帧头,并在末尾添加帧校验序列,形成完整的以太网帧。

以太网帧格式

各字段的作用如下。

  • **目的 MAC 地址(6 字节):**标识当前链路上的目标接收设备。

  • **源 MAC 地址(6 字节):**标识发送该帧的设备。

  • **类型字段(2 字节):**告诉接收方,数据部分应该交给哪个上层协议处理。

  • **数据与填充:**通常承载 IP 报文,也可以承载 ARP 报文等。

  • **FCS(Frame Check Sequence,帧校验序列,4 字节):**用于检测帧传输过程中是否出现差错。

3. 类型字段如何完成协议分用?

接收方拿到一个以太网帧后,首先需要识别它的数据部分属于哪一种协议。

以太网通过类型字段完成这个任务,常见取值如下:

类型字段 含义
0x0800 IPv4
0x0806 ARP
0x8035 RARP

例如,接收方发现类型字段是 0x0800,就将数据部分交给 IPv4 协议处理;如果发现类型字段是 0x0806,则交给 ARP 处理。

整个过程可以概括为:

复制代码
收到以太网帧
    |
    v
检查目的 MAC 地址
    |
    +-- 不是本机地址,也不是需要接收的组播/广播地址
    |       |
    |       v
    |      丢弃
    |
    v
解析以太网类型字段
    |
    +-- 0x0800 --> IPv4
    |
    +-- 0x0806 --> ARP
    |
    +-- 其他类型 --> 对应协议处理

这里有两个重要概念:

  • **解包:**根据协议格式,分离报头与数据部分。

  • **分用:**根据协议字段,决定将数据交给哪个协议处理。

这种机制并不只存在于数据链路层。在 IP 层,协议字段也会帮助内核区分 TCP、UDP 等上层协议。

三、MTU 限制:为什么以太网帧不能无限大?

1. MTU 是什么?

MTU 是 Maximum Transmission Unit 的缩写,中文称为最大传输单元。

对于常见的以太网,MTU 通常为 1500 字节。这里指的是以太网能够承载的最大 IP 报文长度,而不是整个以太网帧的长度。

复制代码
以太网帧
+----------------+----------------------------+----------+
| 以太网头部 14B | IP 报文,最大通常为 1500B  | FCS 4B   |
+----------------+----------------------------+----------+

因此,不带 VLAN 标签的标准以太网帧最大通常是:

++14+1500+4=1518++

如果 IP 报文超过当前链路的 MTU,发送方就需要根据具体协议和配置进行分片,或者通过路径 MTU 发现机制调整发送报文大小。

对于 IPv4,在 IP 首部为 20 字节、TCP 首部为 20 字节且没有额外选项时:

++1500-20-20=1460++

MSS 是 TCP 最大报文段数据长度,不包括 IP 首部和 TCP 首部。它与 MTU 密切相关,但两者并不是同一个概念。

2. 为什么还规定了最小长度?

标准以太网帧也存在最小长度要求。

不带 VLAN 标签的标准以太网帧,从目的 MAC 到 FCS 的长度至少为 64 字节。其中:

  • 以太网头部:14 字节。

  • 数据部分:至少 46 字节。

  • FCS:4 字节。

因此:

++14+46+4=64++

如果上层交付的数据不足 46 字节,以太网就会通过 Padding(填充)补足数据部分的长度。

例如:

复制代码
IP 报文实际长度:30 字节
以太网数据部分:46 字节
填充长度:16 字节

接收方如何区分真实 IP 报文与填充数据?

答案是:IP 首部中的总长度字段记录了整个 IP 报文的实际长度。接收方根据这个字段确定 IP 报文的结束位置,不会把以太网填充字节当作 IP 数据。

3. 为什么需要限制帧长度?

可以从传输效率和共享信道的使用方式理解。

在传统共享式、半双工以太网中,多个设备可能竞争同一条传输介质。单个帧占用信道的时间越长,其他设备等待的时间也可能越长;发生碰撞时,已发送的数据也可能需要重新发送。

因此,帧长度需要在传输效率、协议开销和信道公平性等因素之间取得平衡。

不过,需要区分历史背景与现代网络:**1500 字节是以太网广泛采用的标准 MTU,并不能简单地说它完全是为了减少碰撞而设定的。**在现代交换式全双工以太网中,正常链路通常不存在传统共享式以太网的碰撞问题,MTU 仍然有其重要作用。

四、局域网通信:为什么其他主机也能收到数据?

1. 从主机 A 给主机 E 发送数据说起

假设一个局域网中有五台主机:

复制代码
        同一个局域网
  +---------------------------+
  |                           |
  |  A      B      C      D   E
  |                           |
  +---------------------------+

主机 A 要给主机 E 发送一个以太网帧,会在帧头中填写:

复制代码
源 MAC:A 的 MAC 地址
目的 MAC:E 的 MAC 地址

当数据帧通过共享介质传输时,同一链路上的其他设备也可能接收到这个帧。

那么,B、C、D 收到之后会怎样?

它们会在网卡或链路层接收路径中检查目的 MAC 地址。如果该帧不是发给自己的,也不是自己需要接收的广播或组播帧,就会将其丢弃,而不会正常交给上层协议处理。

只有符合接收条件的主机 E,才会继续解析帧类型,并将数据交给对应的协议。

因此,从主机 A 的视角看,它是在向主机 E 发送数据;但在共享式以太网中,数据帧并不是天然只被 E 物理接收到。

2. 混杂模式与抓包

正常情况下,网卡会过滤一部分与本机无关的帧。而将网卡设置为混杂模式(Promiscuous Mode)后,网卡会尽可能把收到的帧交给操作系统的抓包程序,而不只是交付目的 MAC 匹配的帧。

这也是 Wireshark、tcpdump 等工具在适当的网络环境下能够抓取其他设备流量的基础之一。

不过,**混杂模式不意味着能够看到整个互联网的所有数据。**它只能观察网卡实际能够接收到的流量。交换机、无线网络的工作方式、抓包权限以及网络拓扑,都会影响可见范围。

如果抓到的是明文 HTTP 等未加密业务数据,可能会泄露具体内容;如果是 HTTPS,通常仍然可以看到部分公开的网络元数据,但无法直接读取正常加密保护下的 HTTP 正文。

因此,涉及敏感信息时,应使用 HTTPS 等加密协议,而不是依赖局域网内的 MAC 地址过滤来保护数据。

五、碰撞检测与交换机:局域网如何提高通信效率?

1. 什么是数据碰撞?

在传统共享式、半双工以太网中,如果多台主机同时发送数据,它们的信号可能发生冲突,导致数据帧无法正确传输。这种现象称为数据碰撞(Collision)。

以太网曾经使用 CSMA/CD 机制处理这类问题。

CSMA/CD 的全称是载波监听多路访问/碰撞检测。其基本过程如下:

复制代码
主机准备发送数据
       |
       v
监听信道是否空闲
       |
       +-- 信道忙 --> 等待
       |
       +-- 信道空闲
               |
               v
            发送数据
               |
               v
            检测碰撞
               |
        +------+------+
        |             |
      未碰撞         发生碰撞
        |             |
        v             v
     发送完成      停止发送
                      |
                      v
                  随机等待
                      |
                      v
                    重发

这里有一个关键点:碰撞检测与处理是链路接入机制的一部分,而 TCP 的超时重传属于传输层的可靠传输机制。两者解决的问题不同。

需要注意,CSMA/CD 主要适用于传统共享式、半双工以太网。现代交换式全双工以太网的链路通常可以同时收发数据,不需要依靠 CSMA/CD 处理碰撞。

2. 交换机是如何工作的?

当局域网中的主机越来越多时,可以使用交换机将不同设备连接起来。

交换机工作在数据链路层,主要根据 MAC 地址和端口之间的对应关系转发以太网帧。

假设主机 A 要向主机 B 发送数据,而主机 C 要向主机 D 发送数据。

如果交换机已经学习到 A、B、C、D 分别连接在哪些端口,那么 A 发给 B 的帧可以只从 B 对应的端口转发,C 发给 D 的帧也可以只从 D 对应的端口转发。

两个通信过程就可以同时进行,而不必像传统共享式以太网那样争用同一条共享信道。

严格来说,现代交换机通常是通过每个端口形成独立的碰撞域来减少碰撞,而不是简单地将整个网络划分成左右两个碰撞域。全双工交换链路正常工作时不会发生传统以太网碰撞。

3. 交换机如何学习 MAC 地址?

交换机内部维护着一张 MAC 地址转发表,用来记录 MAC 地址与端口的对应关系。

例如:

MAC 地址 对应端口
MAC-A eth0
MAC-B eth1
MAC-C eth2

交换机主要通过以下过程完成自学习和转发。

第一步:学习源 MAC 地址。

交换机收到一个数据帧后,会读取源 MAC 地址,并记录这个地址是从哪个端口进入的。

例如,交换机从 eth0 收到源 MAC 为 A 的帧,就会学习到 A 位于 eth0。

第二步:查询目的 MAC 地址。

交换机查询转发表,寻找目的 MAC 对应的端口。

  • 如果找到了,就从对应端口转发,通常不会从接收端口发回去。

  • 如果没有找到,就会在同一 VLAN 中除入端口以外的其他适用端口进行泛洪(Flooding)。

第三步:不断更新转发表。

随着网络中设备不断通信,交换机会逐渐学习更多 MAC 地址与端口的对应关系。表项也会根据设备活动和老化机制更新。

需要明确:交换机并不是只负责把数据帧"传过去"的简单导线,而是根据 MAC 地址学习结果进行选择性转发的设备。

六、数据链路层是否保证可靠传输?

答案是:以太网的数据链路层不提供类似 TCP 那样的端到端可靠传输保证。

以太网帧末尾的 FCS 可以检测某些传输错误。发现帧校验失败后,接收方通常会丢弃该帧。但以太网本身不会因为这个帧被丢弃,就自动向发送方确认并要求重传。

可以用下面的过程理解:

复制代码
主机 A
  |
  | 发送以太网帧
  v
当前链路
  |
  +-- 正常到达 --> 接收方继续处理
  |
  +-- 发生差错 --> 帧可能被丢弃
                       |
                       v
                 以太网不保证重传

TCP 则可以在更高的层次上,通过确认、序列号、超时重传等机制,处理数据丢失和乱序等问题。

因此,我们要区分两件事:

  • **差错检测:**发现收到的数据可能已经损坏。

  • **可靠传输:**通过确认、重传等机制,尽可能确保数据被正确交付。

数据链路层可以提供差错检测,但这不等于它保证了端到端的可靠传输。

七、ARP 协议:知道下一跳 IP,如何得到下一跳 MAC?

1. 为什么需要 ARP?

前面已经讲过,网络层通过路由表确定下一跳 IP 地址,而以太网发送数据帧时需要填写目的 MAC 地址。

这就产生了一个问题:

假设主机 A 的路由查询结果是:

复制代码
下一跳 IP:192.168.1.1

但是主机 A 并不知道 192.168.1.1 对应的 MAC 地址,应该怎么办?

这就是 ARP 协议要解决的问题。

ARP 的全称是 Address Resolution Protocol,即地址解析协议。对于 IPv4 以太网,ARP 用于查询某个 IPv4 地址对应的链路层硬件地址。

需要注意,ARP 解决的是当前链路上的下一跳地址解析问题,而不是把最终目标 IP 直接转换成跨越整个互联网的 MAC 地址。

例如:

复制代码
主机 A
  |
  | 目的 IP:公网服务器 IP
  | 下一跳 IP:默认网关 IP
  | 目的 MAC:默认网关 MAC
  v
默认网关
  |
  | 查路由表,确定下一跳
  | 重新封装新的 MAC 帧
  v
下一段网络

如果目标 IP 不在本地子网,主机通常需要解析默认网关的 MAC 地址,而不是远端服务器的 MAC 地址。

2. ARP 报文的基本结构

ARP 报文包含以下字段:

字段 作用
硬件类型 表示使用的链路层类型
协议类型 表示要解析的网络层协议类型
硬件地址长度 硬件地址的字节数
协议地址长度 协议地址的字节数
OP 区分请求和应答
发送端 MAC 请求方或应答方的 MAC 地址
发送端 IP 请求方或应答方的 IP 地址
目标 MAC 被查询方的 MAC 地址,具体取值取决于报文类型
目标 IP 要查询的 IP 地址

在常见的 IPv4 以太网 ARP 报文中:

  • 硬件类型为 1,表示以太网。

  • 协议类型为 0x0800,表示 IPv4。

  • 硬件地址长度为 6 字节。

  • 协议地址长度为 4 字节。

  • OP 为 1 表示请求,2 表示应答。

这类 ARP 报文的长度为 28 字节。由于以太网数据部分至少需要 46 字节,因此通常还需要填充 18 字节。

八、ARP 请求与应答:从广播到单播的完整过程

假设主机 A 想要查询主机 E 的 MAC 地址。

主机 A 已知:

复制代码
主机 A 的 IP:192.168.1.10
主机 A 的 MAC:AA-AA-AA-AA-AA-AA

主机 E 的 IP:192.168.1.20
主机 E 的 MAC:未知

1. 第一步:主机 A 发送 ARP 请求

主机 A 构造 ARP 请求报文,并填写自己的 MAC 地址、IP 地址以及要查询的目标 IP 地址。

由于它还不知道主机 E 的 MAC 地址,因此 ARP 请求中的目标 MAC 地址通常填零。

随后,主机 A 将这个 ARP 报文封装进以太网帧:

复制代码
以太网帧
+--------------------------------+
| 目的 MAC:FF-FF-FF-FF-FF-FF    |
+--------------------------------+
| 源 MAC:AA-AA-AA-AA-AA-AA      |
+--------------------------------+
| 类型:0x0806                   |
+--------------------------------+
| ARP 请求报文                   |
| OP = 1                         |
| 发送端 IP = 192.168.1.10       |
| 目标 IP = 192.168.1.20         |
+--------------------------------+

这里的 FF-FF-FF-FF-FF-FF 是以太网广播地址,表示当前广播域中的相关设备都可以接收这个帧。

2. 第二步:局域网内的主机接收请求

主机 B、C、D、E 都可能收到这个广播帧。

它们首先通过以太网帧类型字段发现,这个帧承载的是 ARP 报文,然后将报文交给 ARP 处理逻辑。

ARP 处理逻辑会检查 OP 字段,判断这是一个请求还是应答。对于请求报文,还需要检查目标 IP 是否是自己的 IP 地址。

复制代码
主机 B 收到请求
    |
    v
OP = 1,是请求
    |
    v
目标 IP 是否为 B 的 IP?
    |
    +-- 否 --> 不为该请求提供应答
    |
    +-- 是 --> 构造 ARP 应答

因此,只有目标 IP 对应的主机 E 会正常回应这次请求。

需要注意,ARP 的 OP 字段用于区分请求和应答,而目标 IP 匹配则用于判断请求是不是在查询本机。

3. 第三步:主机 E 单播返回 ARP 应答

主机 E 确认请求中的目标 IP 是自己的 IP 地址后,便可以构造 ARP 应答。

复制代码
以太网帧
+--------------------------------+
| 目的 MAC:AA-AA-AA-AA-AA-AA    |
+--------------------------------+
| 源 MAC:EE-EE-EE-EE-EE-EE      |
+--------------------------------+
| 类型:0x0806                   |
+--------------------------------+
| ARP 应答报文                   |
| OP = 2                         |
| 发送端 IP = 192.168.1.20       |
| 发送端 MAC = EE-EE-EE-EE-EE-EE |
| 目标 IP = 192.168.1.10         |
| 目标 MAC = AA-AA-AA-AA-AA-AA   |
+--------------------------------+

这次应答的目的 MAC 地址已经明确,所以主机 E 可以通过单播方式将应答发送给主机 A。

其他主机如果收到这个单播帧,通常会因为目的 MAC 地址不匹配而在接收路径中将其过滤掉。

4. 第四步:主机 A 获得目标 MAC 地址

主机 A 收到 ARP 应答后,会解析报文,确认这是 OP 为 2 的应答,并从中获得:

复制代码
192.168.1.20
        |
        v
EE-EE-EE-EE-EE-EE

主机 A 随后可以将 IP 报文封装进以太网帧,通过目的 MAC 地址向主机 E 发送数据。

完整流程如下:

九、ARP 缓存:为什么不需要每次通信都广播?

如果每次发送数据都重新进行 ARP 查询,那么局域网中就会产生大量重复的广播请求。

因此,操作系统通常会将解析得到的 IP 地址与 MAC 地址映射关系暂存在本机的 ARP 缓存中。

例如:

IP 地址 MAC 地址
192.168.1.1 11-11-11-11-11-11
192.168.1.20 EE-EE-EE-EE-EE-EE

当主机 A 再次向 192.168.1.20 发送数据时,如果缓存中存在有效的映射关系,就可以直接使用对应的 MAC 地址,不必再次广播 ARP 请求。

缓存中的记录通常具有老化机制。记录过期、失效或需要重新验证时,操作系统可能重新执行地址解析。

在 Linux 中,可以使用以下命令查看邻居表:

复制代码
ip neigh

例如,输出中可能包含:

复制代码
192.168.1.1 dev eth0 lladdr 11:11:11:11:11:11 REACHABLE

这表示系统记录了该 IPv4 地址对应的链路层地址,以及相关接口和邻居状态。

严格来说,Linux 使用邻居子系统管理这类映射,ARP 是 IPv4 对应的地址解析机制;IPv6 则使用邻居发现协议(NDP),而不是 ARP。

十、总结:把以太网、交换机与 ARP 串起来

回顾整个数据链路层的工作过程,可以得到一条完整的通信链路。

复制代码
用户需要与目标主机通信
          |
          v
网络层根据目的 IP 查询路由表
          |
          v
确定下一跳 IP 地址
          |
          v
查询 ARP 缓存
          |
          +-- 命中 --> 直接获取下一跳 MAC
          |
          +-- 未命中 --> 广播 ARP 请求
                            |
                            v
                       获取 ARP 应答
                            |
                            v
                       获得下一跳 MAC
          |
          v
封装以太网帧
          |
          v
交换机依据 MAC 地址学习结果转发
          |
          v
下一跳设备接收并处理数据

本文的核心知识点可以归纳为:

  1. **IP 地址与 MAC 地址的分工:**IP 地址负责网络层寻址,MAC 地址负责当前链路上的帧交付。

  2. **以太网帧格式:**通过源 MAC、目的 MAC、类型字段、数据部分和 FCS 完成帧封装与处理。

  3. **MTU 与帧长度:**以太网通常使用 1500 字节 MTU,并通过填充满足最小帧长度要求。

  4. **交换机的工作原理:**通过学习源 MAC 与端口的对应关系,实现定向转发并减少不必要的流量扩散。

  5. **数据链路层的可靠性边界:**帧校验可以检测差错,但以太网不提供 TCP 那样的端到端可靠传输保证。

  6. **ARP 的工作原理:**通过广播请求、单播应答,获得 IPv4 下一跳对应的 MAC 地址,并利用缓存减少重复查询。

至此,从网络层查找下一跳,到数据链路层封装 MAC 帧,再到交换机转发和 ARP 地址解析,这条通信链路就基本闭环了。

下一步可以继续学习 NAT:当内网主机使用私有 IP 地址访问公网时,路由器如何通过地址转换让内网与公网通信,以及内网主机如何接受来自公网的连接请求。

相关推荐
迷途之人不知返1 小时前
【文件系统】-1-磁盘与扇区的定位方法
linux
无足鸟ICT1 小时前
【RHCA+】yum源配置(软件仓库)
linux·运维
国科安芯1 小时前
空间锂离子电池组管理系统CANFD通信网络的辐射可靠性设计
网络·信息与通信·canfd·电池·低轨卫星·抗辐射
2401_868534781 小时前
网规物流企业网络问题
网络
0+1111 小时前
Linux --IP分片和组装
linux·网络·tcp/ip
Kira Skyler1 小时前
CVE-2026-99999 deferred-metadata trust inversion 原理分析.md
linux
zxanz12 小时前
SSL 证书该怎么申请?操作复杂吗?
网络·网络协议·ssl
Initialize-le2 小时前
服务器时间不准?NTP 时钟同步五步排查
运维·服务器
AR-26710-2 小时前
Linux Day24——TCP/IP分层与封装
linux·运维