2、以太网帧与MAC地址:MAC地址结构,以太网帧格式,ARP协议工作原理
聊完粘包拆包,咱们得先搞清楚数据在网络上到底是怎么“打包”的。你想想看,应用层的数据要发出去,得一层层往下封装。到了数据链路层,就绕不开以太网帧和MAC地址。这一节,我就带你把这层底裤扒干净。
2.1 MAC地址结构
MAC地址,也叫物理地址、硬件地址。说白了,就是网卡在出厂时被烧录的一个唯一标识。我刚开始做嵌入式开发时,总觉得这东西跟IP地址差不多,后来踩了坑才明白——它俩完全不是一个层面的东西。
MAC地址长什么样?48位,6个字节。通常用十六进制表示,比如 00:1A:2B:3C:4D:5E。前3个字节是OUI(组织唯一标识符),由IEEE分配给厂商;后3个字节是厂商自己分配的序列号。
MAC地址结构拆解:
- 第1字节最低位(bit 0):I/G位。0表示单播,1表示组播。
- 第1字节次低位(bit 1):G/L位。0表示全局唯一(由IEEE分配),1表示本地管理。
- 前3字节(OUI):厂商代码。比如00:1A:2B是某厂商的。
- 后3字节(NIC):接口序列号。由厂商自行分配,保证不重复。
我曾经在调试一个网络设备时,发现两台设备的MAC地址一模一样。查了半天,原来是某小厂烧录时没按规范来,直接复制了。嗯,这种坑,遇到了你就知道MAC地址唯一性有多重要。
小技巧:抓包时看到MAC地址第一个字节是奇数(比如01:xx:xx:xx:xx:xx),那一定是组播或广播地址。广播地址就是全F:FF:FF:FF:FF:FF:FF。
2.2 以太网帧格式
数据在以太网上传输,必须封装成帧。目前最常用的是Ethernet II帧格式,也叫DIX帧。IEEE 802.3也有自己的帧格式,但实际网络中99%都是Ethernet II。
以太网帧长什么样?我直接给你画出来:
+----------------+----------------+----------------+----------------+----------------+----------------+
| 前导码 (7B) | 帧定界符 (1B) | 目标MAC (6B) | 源MAC (6B) | 类型/长度 (2B) | 数据 (46-1500B) |
+----------------+----------------+----------------+----------------+----------------+----------------+
| | FCS (4B) |
+-----------------------------------------------------------------------------------------------+---------------+
字段说明:
| 字段 | 长度 | 说明 |
|---|---|---|
| 前导码 | 7字节 | 用于同步时钟,内容是10101010...的交替位 |
| 帧定界符(SFD) | 1字节 | 固定为10101011,标志帧开始 |
| 目标MAC地址 | 6字节 | 接收方网卡的MAC地址 |
| 源MAC地址 | 6字节 | 发送方网卡的MAC地址 |
| 类型/长度 | 2字节 | Ethernet II中表示上层协议类型(如0x0800=IP),802.3中表示数据长度 |
| 数据 | 46-1500字节 | 上层协议数据(IP包),不足46字节需填充 |
| FCS | 4字节 | 帧校验序列,使用CRC32校验整个帧(不含前导码和SFD) |
注意:数据字段最小46字节,最大1500字节。1500就是MTU(最大传输单元)。如果IP包超过1500字节,就得分片。我在做视频传输优化时,就遇到过MTU设置不当导致大量分片重传的问题,性能直接掉一半。
这里有个细节:类型字段如果值大于等于0x0600(1536),就是Ethernet II帧,表示上层协议类型;如果小于等于0x05DC(1500),就是802.3帧,表示数据长度。实际抓包时,你看到的几乎都是Ethernet II帧。
2.3 ARP协议工作原理
现在问题来了:我知道目标IP地址,但不知道目标MAC地址,怎么把帧发出去?这就是ARP协议要干的事。
ARP(Address Resolution Protocol),地址解析协议。它的作用很简单:根据IP地址获取MAC地址。我当年第一次接触这个协议时,觉得它太简单了,不就是问一下嘛。后来做网络诊断时才发现,ARP攻击、ARP欺骗、ARP缓存超时……坑多着呢。
ARP工作原理分几步:
- 查询ARP缓存:先看本地ARP缓存表里有没有目标IP对应的MAC地址。有就直接用,没有就发ARP请求。
- 发送ARP请求:广播一个ARP请求包。目标MAC地址填全F(广播地址),问“谁的IP是192.168.1.1?请告诉我你的MAC地址”。
- 目标回复:IP地址匹配的设备,单播回复一个ARP应答包,告诉对方自己的MAC地址。
- 更新缓存:请求方收到应答后,把IP-MAC映射写入ARP缓存,并设置超时时间(通常2-10分钟)。
ARP报文格式:
+----------------+----------------+----------------+----------------+
| 硬件类型 (2B) | 协议类型 (2B) | 硬件地址长度(1)| 协议地址长度(1)|
+----------------+----------------+----------------+----------------+
| 操作码 (2B) | 发送方MAC (6B) | 发送方IP (4B) | 目标MAC (6B) |
+----------------+----------------+----------------+----------------+
| 目标IP (4B) |
+----------------+
| 字段 | 长度 | 典型值 |
|---|---|---|
| 硬件类型 | 2字节 | 1表示以太网 |
| 协议类型 | 2字节 | 0x0800表示IPv4 |
| 硬件地址长度 | 1字节 | 6(MAC地址长度) |
| 协议地址长度 | 1字节 | 4(IPv4地址长度) |
| 操作码 | 2字节 | 1=ARP请求,2=ARP应答 |
| 发送方MAC | 6字节 | 发送者的MAC地址 |
| 发送方IP | 4字节 | 发送者的IP地址 |
| 目标MAC | 6字节 | 请求时填0,应答时填目标MAC |
| 目标IP | 4字节 | 要解析的IP地址 |
ARP缓存表示例:
192.168.1.1 00:1A:2B:3C:4D:5E 动态 2分钟
192.168.1.2 00:1A:2B:3C:4D:5F 动态 5分钟
192.168.1.100 00:1A:2B:3C:4D:60 静态 永不过期
我曾经遇到过一个问题:公司内网突然大面积断网,排查发现是有人伪造了网关的ARP应答,导致所有设备的ARP缓存都被污染了。这就是典型的ARP欺骗攻击。从那以后,我养成了在关键设备上配置静态ARP条目的习惯。
避坑指南:ARP请求是广播,但ARP应答是单播。如果你抓包发现大量ARP请求重复发送,说明网络中有设备在频繁查询,可能是ARP缓存超时设置太短,或者有ARP扫描行为。
下面这张图,我把MAC地址、以太网帧、ARP协议的关系串起来了:
从这张图可以看得很清楚:上层协议(IP)需要知道目标MAC地址才能封装以太网帧。如果不知道,就触发ARP协议去问。问到了,缓存起来,下次直接用。
重要提醒:ARP只用于IPv4。IPv6使用NDP(邻居发现协议)来完成类似功能。另外,ARP工作在数据链路层和网络层之间,但它本身不依赖IP,只依赖MAC地址。嗯,这个边界要搞清楚。
最后总结一下这一节的核心要点:
- MAC地址:48位,前3字节OUI+后3字节NIC,第1字节最低位标识单播/组播。
- 以太网帧:Ethernet II格式最常用,包含目标MAC、源MAC、类型、数据、FCS。MTU=1500字节。
- ARP协议:广播请求,单播应答。结果缓存在ARP表中,有超时时间。静态ARP可以防欺骗。