ARP 协议是什么?IP 到 MAC 地址转换全流程详解
两台电脑在同一个局域网里聊天,光知道对方的 IP 还不够。
数据真正发出去的时候,网卡认的是 MAC 地址,不是 IP。
那从 IP 怎么找到 MAC?这就是 ARP 干的活。
我第一次抓包看到一堆 who has 192.168.1.1? tell 192.168.1.66 的广播包时,还纳闷这是啥。
后来才明白,这就是 ARP 在满网吼着问路。
ARP 协议是什么
ARP 是地址解析协议(Address Resolution Protocol),作用是把 32 位的 IPv4 地址解析成 48 位的 MAC 地址。
说白了,就是「我知道你的 IP,但我得问出你的网卡硬件地址,才能把数据帧发给你」。
它有几个关键特征:
- 工作在数据链路层和网络层之间,属于局域网范围内的协议
- 只在同一个广播域(通常是同一子网)里直接生效
- 请求用广播发,应答用单播回
为什么需要它?
因为 IP 是逻辑地址,可以随便配;
MAC 是烧在网卡里的物理地址,全球基本唯一。
两台机器在以太网上真正对话,最终靠的是 MAC。
IP 到 MAC 这一步翻译,绕不开 ARP。
ARP 的工作流程
主机 A 想给主机 B 发数据,大致走这几步:
- A 先判断 B 的 IP 是不是和自己在同一子网(拿子网掩码做与运算比较)
- 同网段:A 在本地缓存里查 B 的 MAC,查不到就广播一个 ARP 请求,目的 MAC 填
FF:FF:FF:FF:FF:FF,喊「谁是 192.168.1.5,把你的 MAC 告诉 192.168.1.66」 - 网段内所有主机都会收到这个广播,但只有 IP 匹配的 B 才理你
- B 用单播回一个 ARP 应答,把自己的 MAC 塞进去
- A 收到后,把 B 的 IP-MAC 对应关系写进缓存表,后面再发就直接查表,不用每次都广播
这里有个常被忽略的点:跨网段怎么办?
如果 B 不在同一子网,A 不会去问 B 的 MAC,而是去问网关的 MAC。
数据先发给网关,由网关(路由器)接力转发。
所以你在跨网段通信时抓包,看到的 ARP 请求往往是冲着网关 IP 去的,不是目标主机。
这个细节我以前一直没绞清楚,直到自己搭了两个 VLAN 测试才搞明白。
ARP 报文格式
ARP 报文封装在以太网帧里。
一个完整的「以太网帧头 + ARP 数据」长这样,其中 ARP 数据部分针对 IPv4 over 以太网固定为 28 字节。
先看外层以太网帧头:
| 字段 | 长度 | 说明 |
|---|---|---|
| 以太网目的地址 | 6 字节 | ARP 请求时填全 1(FF:FF:FF:FF:FF:FF),即广播地址 |
| 以太网源地址 | 6 字节 | 发送方网卡的 MAC 地址 |
| 帧类型 | 2 字节 | 标识上层数据类型,ARP 固定为 0x0806 |
再看里层 ARP 数据(28 字节):
| 字段 | 长度 | 说明 |
|---|---|---|
| 硬件类型 | 2 字节 | 硬件地址的类型,以太网为 1 |
| 协议类型 | 2 字节 | 要映射的协议地址类型,IPv4 为 0x0800 |
| 硬件地址长度 | 1 字节 | MAC 地址长度,值为 6 |
| 协议地址长度 | 1 字节 | IP 地址长度,IPv4 值为 4 |
| 操作类型 | 2 字节 | 1=ARP 请求,2=ARP 应答,3=RARP 请求,4=RARP 应答 |
| 发送端 MAC | 6 字节 | 发送方硬件地址 |
| 发送端 IP | 4 字节 | 发送方协议地址 |
| 目标端 MAC | 6 字节 | 目标硬件地址(请求时未知,填全 0) |
| 目标端 IP | 4 字节 | 目标协议地址 |
注意第二行有个容易踩的坑:ARP 请求时,目标端 MAC 字段是填全 0 的,因为这正是要问出来的东西。
原来很多笔记直接说「填目的硬件地址」,其实请求阶段根本不知道,应答时才有值。
ARP 缓存表
每查到一次 IP-MAC 映射,系统都会缓存下来,存在 ARP 缓存表里,避免重复广播。
想看自己机器的缓存,命令很简单:
- Windows / Linux / macOS:
arp -a - Linux 还可以用
ip neigh
缓存条目不是永久的。
动态条目一般几分钟就过期(Windows 默认两分钟左右,超时后会再次发起 ARP),过期后重新解析。这么设计是为了应对设备更换网卡、IP 重新分配这类变化。
免费 ARP 是什么
免费 ARP(Gratuitous ARP)是主机主动广播一条「查询自己 IP」的 ARP 请求,但其实它并不指望谁回应。它有两个常见用途:
- 检测 IP 冲突:如果有别人回应了,说明这个 IP 已经被占用
- 主动更新别人缓存:比如设备换了网卡,广播一下让全网刷新对它的 MAC 记录
很多网络设备启动时都会发免费 ARP,抓包能看到。
ARP 攻击的原理和防御
ARP 协议有个先天毛病:它无状态、不验证。
也就是说,主机收到一个 ARP 应答,哪怕自己压根没问过,也会照单全收更新缓存。
攻击者就钻这个空子。
常见的 ARP 欺骗是这样玩的:攻击者不停地向受害者广播伪造的应答,声称「网关的 MAC 是我」,同时告诉网关「受害者的 MAC 也是我」。
结果两边的流量都先经过攻击者的机器,这就形成了中间人攻击。
轻则断网,重则数据被窃听、篡改。
怎么防?常见手段有这么几种:
| 防御方法 | 思路 |
|---|---|
| 静态 ARP 绑定 | 手动把网关 IP-MAC 写死,不接受动态更新 |
| ARP 防火墙 | 监控异常 ARP 应答并拦截 |
| DAI(动态 ARP 检测) | 交换机层面校验 ARP 报文合法性 |
| 端口安全 + DHCP Snooping | 在接入层限制非法 MAC 和伪造应答 |
家用场景里,路由器和电脑双向做静态绑定,基本就能挡住大部分 ARP 欺骗了。
企业环境则更依赖交换机的 DAI。
常见问题
ARP 和 RARP 有什么区别?
ARP 是从 IP 查 MAC,RARP(逆地址解析协议)反过来,从 MAC 查 IP。RARP 早年用于无盘工作站启动时获取自己的 IP,现在基本被 DHCP 取代了,了解即可。
ARP 工作在 OSI 哪一层?
说法不太统一。
比较主流的观点是它横跨数据链路层和网络层:报文封装在以太网帧里(链路层),但解析的是 IP 地址(网络层)。不少教材直接把它归到链路层。
为什么 ARP 请求是广播,应答是单播?
请求阶段不知道对方 MAC,只能广播让全网都听到。
而应答时,目标主机已经从请求里拿到了发送方的 IP 和 MAC,直接单播回去就行,没必要再骚扰全网。
ping 不通但能上网,会是 ARP 问题吗?
有可能。
如果 ARP 缓存里网关的 MAC 被投毒成了错误地址,就会出现间歇性断网或定向不通。可以先 arp -a 看看网关那条记录的 MAC 对不对,必要时清缓存(Windows 用 arp -d)重新解析。
总结
ARP 解决的就是一件事:在局域网里,把 IP 翻译成 MAC。
流程不复杂,广播问、单播答、写缓存。
但它「来者不拒」的设计,也埋下了 ARP 欺骗的隐患。
理解了请求应答和缓存机制,再看 ARP 攻击和防御,就顺理成章了。
跨网段问网关、请求包里目标 MAC 填全 0,这两个点我自己当初绕了挺久,希望能帮你少走点弯路。
如果你对 ARP 缓存中毒排查或者免费 ARP 还有疑问,欢迎在评论区交流~~~
版权声明
未经授权,禁止转载本文章。
如需转载请保留原文链接并注明出处。即视为默认获得授权。
未保留原文链接未注明出处或删除链接将视为侵权,必追究法律责任!
本文原文链接: https://fiveyoboy.com/articles/arp-protocol-explained/
备用原文链接: https://blog.fiveyoboy.com/articles/arp-protocol-explained/