2. 物理层与数据链路层:以太网帧结构、MAC地址、ARP协议原理与抓包分析
各位好,我是老周。今天咱们聊聊网络里最底层的两兄弟——物理层和数据链路层。很多人觉得这两层太“硬”,没什么好讲的。其实不然。我做了十几年网络,踩过的坑有一半都跟这两层有关。你想想看,上层应用跑得再花哨,底层要是传错了比特,一切都是白搭。
这一章,我会带着大家从以太网帧结构入手,把MAC地址、ARP协议这些基础但关键的东西掰开揉碎。最后,咱们用Wireshark抓个包,亲眼看看这些协议在线上是怎么跑的。
2.1 以太网帧结构:比特在线上怎么排队
物理层负责把0和1变成电信号或光信号发出去。数据链路层呢,负责把这些比特组织成有意义的“帧”。说白了,就是给比特排好队,贴上标签,告诉接收方:“这是谁发的,要发给谁,里面装的是什么。”
标准的以太网帧长这样:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 前导码 | 7 | 同步时钟,让接收方对齐比特流 |
| 帧起始定界符 | 1 | 标志帧正式开始 |
| 目的MAC地址 | 6 | 接收方的硬件地址 |
| 源MAC地址 | 6 | 发送方的硬件地址 |
| 类型/长度 | 2 | 上层协议类型(如0x0800代表IP)或数据长度 |
| 数据载荷 | 46-1500 | 上层传下来的数据包 |
| 帧校验序列 | 4 | CRC校验,检查传输是否出错 |
这里有个关键点:数据载荷最小46字节,最大1500字节。为什么是46?因为帧总长度不能小于64字节(14字节头部 + 46字节数据 + 4字节尾部)。小于64字节的帧叫“ runt 帧”,接收方会直接丢弃。我曾经在项目中遇到过网卡驱动bug,疯狂发短帧,结果整个局域网都在丢包,排查了两天才找到原因。
2.2 MAC地址:设备的身份证
MAC地址,也叫硬件地址,是网络设备的唯一标识。它烧录在网卡的ROM里,理论上全球唯一。长度48位,通常写成6组十六进制数,比如 00:1A:2B:3C:4D:5E。
MAC地址的结构:
- 前24位:组织唯一标识符,由IEEE分配给厂商。比如00:1A:2B是某厂商的。
- 后24位:厂商自己分配的序列号,保证同一厂商下不重复。
这里有个小细节:MAC地址的第1字节的最低2位有特殊含义。
- 第1位(I/G位):0表示单播,1表示组播或广播。
- 第2位(U/L位):0表示全球唯一,1表示本地管理。
2.3 ARP协议原理:IP地址怎么找到MAC地址
现在问题来了:上层用IP地址通信,底层却只认MAC地址。怎么把IP地址翻译成MAC地址?这就是ARP协议干的事。
ARP(地址解析协议)的工作原理其实很简单:
- 主机A想给主机B发数据,但只知道B的IP地址,不知道B的MAC地址。
- A在局域网里广播一个ARP请求:“谁的IP是192.168.1.2?请把你的MAC地址告诉我。”
- 所有主机都收到这个广播,但只有B回应:“我是192.168.1.2,我的MAC是00:1A:2B:3C:4D:5E。”
- A收到回应后,把IP和MAC的对应关系缓存到本地ARP表里,下次直接用。
ARP报文结构:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 硬件类型 | 2 | 1表示以太网 |
| 协议类型 | 2 | 0x0800表示IP |
| 硬件地址长度 | 1 | MAC地址长度,固定6 |
| 协议地址长度 | 1 | IP地址长度,固定4 |
| 操作码 | 2 | 1表示请求,2表示应答 |
| 发送方MAC | 6 | 发送方的硬件地址 |
| 发送方IP | 4 | 发送方的IP地址 |
| 目标MAC | 6 | 请求时为全0,应答时填目标MAC |
| 目标IP | 4 | 目标主机的IP地址 |
下面这张图展示了ARP请求与应答的完整流程:
2.4 抓包分析:亲眼看看协议怎么跑
光说不练假把式。咱们用Wireshark抓个包,看看ARP和以太网帧的真实面貌。
实验环境: 两台Windows主机,IP分别是192.168.1.1和192.168.1.2,连在同一台交换机上。
操作步骤:
- 在主机A上打开Wireshark,选择连接交换机的网卡。
- 设置过滤条件:
arp或eth.addr == 00:1A:2B:3C:4D:5E。 - 在主机A的命令行执行
ping 192.168.1.2。 - 观察Wireshark捕获到的数据包。
你会看到类似这样的结果:
No. Time Source Destination Protocol Info
1 0.000000 00:1A:2B:3C:4D:5E FF:FF:FF:FF:FF:FF ARP Who has 192.168.1.2? Tell 192.168.1.1
2 0.000123 00:1A:2B:3C:4D:5F 00:1A:2B:3C:4D:5E ARP 192.168.1.2 is at 00:1A:2B:3C:4D:5F
3 0.000456 00:1A:2B:3C:4D:5E 00:1A:2B:3C:4D:5F ICMP Echo (ping) request
4 0.000789 00:1A:2B:3C:4D:5F 00:1A:2B:3C:4D:5E ICMP Echo (ping) reply
看到了吗?第1个包是ARP请求,目标MAC是全F的广播地址。第2个包是ARP应答,目标MAC是主机A的地址。之后才是真正的ICMP ping包。
arp 过滤看ARP交互,再用 icmp 看ping,最后用 ip.addr == 目标IP 看完整会话。分步过滤,效率最高。
双击任意一个ARP包,展开以太网帧头部,你会看到:
- Destination MAC:ARP请求里是FF:FF:FF:FF:FF:FF,应答里是目标主机的MAC。
- Source MAC:发送方的MAC地址。
- Type:0x0806,表示上层是ARP协议。
再展开ARP协议部分,能看到我们刚才表格里列出的所有字段:硬件类型、协议类型、操作码、发送方MAC/IP、目标MAC/IP。嗯,跟理论完全吻合。
2.5 避坑指南:我踩过的那些坑
最后,分享几个我亲身经历过的坑,希望能帮大家少走弯路。