ARP 简述
解析网络层 IP 地址来找寻数据链路层 MAC 地址,它在 IPv4 中极其重要。ARP 最初在 1982 年的 RFC 826 中提出并纳入互联网标准 STD 37。在 IPv6 中,使用的是 NDP(邻居发现协议)用于代替 ARP。
MAC 地址简述
MAC 地址(Media Access Control Address),也称为局域网地址(LAN Address),以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网络设备位置的地址。
以太网简述
是一种计算机局域网技术。IEEE 组织的 IEEE 802.3 标准制定了以太网的技术标准,它规定了包括物理层的连线、电子信号和介质访问层协议的内容。以太网是目前应用最普遍的局域网技术,取代了其他局域网技术如令牌环、FDDI 和 ARCNET。

- 数据帧首部:占 14 字节,包含有目标主机网卡 MAC 地址、源主机网卡 MAC 地址以及数据帧类型标识。
- 数据:从上层(网络层)传递下来的数据包,范围在 [46, 1500] 个字节之间。
- 数据帧尾部:占 4 个字节,是 CRC 校验序列,用来确定数据帧在传输过程中是否有损坏。
ARP 的基本功能
在以太网协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的 MAC 地址。而在 TCP/IP 协议中,网络层和传输层只关心目标主机的 IP 地址以及端口号。这就导致在以太网中使用 IP 协议时,数据链路层的以太网协议接到上层 IP 协议提供的数据中,只包含目的主机的 IP 地址。而没有 MAC 地址就无法最终定位目的主机,于是需要一种方法,根据目的主机的 IP 地址,获得其 MAC 地址。这就是 ARP 协议要做的事情。所谓地址解析(Address Resolution)就是主机在发送数据帧前将目标 IP 地址转换成目标 MAC 地址的过程。

而在点对点链路中不会使用 ARP,实际上在点对点网络中也不会使用 MAC 地址,因为在此类网络中分别已经获取了对端的 IP 地址。
注意:ARP 已经在很多网路层和数据链接层之间得以实现,包括 IPv4、Chaosnet、DECnet 和 Xerox PARC Universal Packet(PUP),使用 IEEE 802 标准。可见,ARP 不仅限于使用在 IPv4 网络,这一点从 ARP 的数据包结构设计中有体现出来。
ARP 的数据包结构
下图为以太网数据帧的数据结构:

- 以太网首部:
- 以太网目的地址和以太网源地址:表示目标设备和发送端设备的以太网地址。其中,目的以太网地址全为 1,即 FF:FF:FF:FF:FF:FF,为广播地址,在本地局域网内,所有的以太网接口都要接收这个数据帧。
- 帧类型:表示以太网数据帧的数据类型。对于 ARP 来说这里是 0x0806,对于 IP 数据报文是 0x0800,还有 RARP(逆地址解析协议)是 0x8035。
NOTE:若以太网数据帧的帧类型是 ARP,那么数据部分就会拥有 ARP 首部。
- 以太网 ARP 字段:
- ARP 首部:
- 硬件类型和协议类型:这两个字段用来描述 ARP 分组。前者表示 ARP 工作在什么类型的网络中,需要什么样的物理地址;后者则表示需要映射的协议地址类型。例如:用来描述 IPv4 时,则协议类型为 IP,硬件类型为以太网的物理地址。所以协议类型为 0x0800,硬件类型为 1,表示以太网地址。
- 硬件地址长度和协议地址长度:用来描述 IPv4 时,分别表示 MAC 地址和 IP 地址的长度,分别为 6 字节和 4 字节。
- 操作码:表示 ARP 数据包的操作类型。
- 1:ARP 请求
- 2:ARP 应答
- 3:RARP 请求
- 4:RARP 应答
- 源硬件地址和目标硬件地址:与以太网首部中的目的以太网地址和源以太网地址重叠。
- 源协议地址和目标协议地址:用来描述 IPv4 时,分别表示源设备 IP 地址和目的设备 IP 地址。
NOTE 1:在发送 ARP 请求时,目标硬件地址是空着的(全为 0),因为 ARP 请求要请求的就是它的值,当目标设备请求收到后,就会把自己的硬件地址写到这个字段,并把操作码改成 2,再应答回去。
NOTE 2:在 ARP 中,有效数据的长度为 28 个字节,不足以太网的最小长度 46 字节长度。所以需要填充字节,填充字节最小长度为 18 个字节。
ARP 的基本工作原理

在每台安装有 TCP/IP 协议的电脑或路由器里都有一个 ARP 缓存表,表里的 IP 地址与 MAC 地址是一对应的,如下表所示。

以主机 A(192.168.38.10)向主机 B(192.168.38.11)发送数据为例。
-
当主机 A 发送数据时,会在自己的 ARP 缓存表中寻找是否有目的 IP 地址。若找到就知道目标 MAC 地址为 00-BB-00-62-C2-02,直接把目的 MAC 地址封装入数据帧,然后通过数据链路层发送就可。
-
若在 ARP 缓存表中没有找到目的 IP 地址,那么主机 A 就会在网络上发送一个广播(ARP Request),目标 MAC 地址是 FF.FF.FF.FF.FF.FF,这表示向同一网段内的所有主机发出这样的询问:“192.168.38.11 的 MAC 地址是什么?”
ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 53.53.53.53 tell 192.168.200.10, length 28

- 网络上其他主机并不响应 ARP 询问,只有主机 B 接收到这个帧时,才向主机 A 做出这样的回应(ARP Response):“ 192.168.38.11 的 MAC 地址是 00-BB-00-62-C2-02”,此回应以单播方式。这样,主机 A 就知道主机 B 的 MAC 地址,它就可以向主机 B 发送信息。

更新自己的 ARP 高速缓存(ARP cache),下次再向主机 B 发送信息时,直接从 ARP 缓存表里查找就可。

NOTE:请求解析方收到 ARP 回应包之后,不会进行任何判断,就直接将对应的 MAC 地址存入自己的 ARP 缓存中,这也是 ARP 投毒攻击的产生原因。
当协议栈中需要再次进行 IP 解析的时候,系统会自动到 ARP 缓存表中查找是否已经存在相应的 IP 表项,若已存在则使用之,若不存在,则执行解析流程,对指定的 IP 进行 ARP 解析。
同时,ARP 缓存表采用老化机制,在一段时间内(一般为 20 分钟)若表中的某一行没有使用,就会被过期删除,这样可减少缓存表的长度,加快查询速度。
ARP 的客户端
Linux 操作系统都会安装 ARP 客户端 —— arp 指令,操作如下:
arp --help
-a 查看缓存中的所有项目
-s, --set 设置一个新的 ARP 项目、不带任何参数表示查看静态 MAC 地址
-d, --delete 人工删除一个静态项目
-v, --verbose be verbose
-n, --numeric don't resolve names
-i, --device specify network interface (e.g. eth0)
-D, --use-device read <hwaddr> from given device
-A, -p, --protocol specify protocol family
-f, --file read new entries from file or from /etc/ethers
-
查看 ARP 缓存表
[root@ctl-host ~]# arp -a ? (172.18.22.205) at 08:9e:01:fc:48:7d [ether] on br0 ? (172.18.22.10) at 52:54:00:bd:23:9e [ether] on br0 gateway (172.18.22.1) at ac:7e:8a:6c:41:c4 [ether] on br0
-
查看 ARP 缓存表的详细信息
[root@ctl-host ~]# arp -nv Address HWtype HWaddress Flags Mask Iface 172.18.22.205 ether 08:9e:01:fc:48:7d C br0 172.18.22.10 ether 52:54:00:bd:23:9e C br0 172.18.22.1 ether ac:7e:8a:6c:41:c4 C br0 Entries: 3 Skipped: 0 Found: 3
-
增加一个静态的 ARP 表项
$ arp –s 157.55.85.212 00-aa-aa-562-c6-09
增加超时条目
$ arp -s 211.161.17.21 00:00:00:00:00:00 temp
ARP announcement(通告)
ARP announcement 是一种特殊的 ARP 请求,ARP 数据包的目的协议地址和源协议地址相同,并且目的硬件地址为全 0。所以,它又会是一个特殊的 ARP 响应,目的协议地址和源协议地址、目的硬件地址和源硬件地址都相同。
ARP announcement 旨在更新其它收到这个通告的主机的 ARP 缓存。这种免费(不请自来)的 ARP 通常用于在主机启动或更换网卡时通知其它主机。又称 GARP(Gratuitous ARP,免费 ARP)。
作用:用作更新 ARP 缓存,网络中的其他主机收到该广播则更新缓存中的条目,收到该广播的主机无论是否存在与 IP 地址相关的条目都会强制更新,若存在旧条目则会将 MAC 更新为广播包中的 MAC。
ARP probe(探针)
ARP Probe 和 ARP announcement 的实现原理类似,但目的不同。ARP Probe 主要用于检测 IPv4 地址冲突。
在主机开始使用一个 IP 地址之前,实现了 RFC 5227 规范的主机必须通过 ARP probe 来测试该 IP 地址是否已经被使用。若 ARP probe 有应答则产生错误消息。
ARP suppression(压制)
禁用主机 ARP,要求配置静态 ARP 缓存才能通信:
ip link set dev eth0 arp off
ARP proxy(代理)
另外,当源主机和目的主机不在同一个局域网中时,即便知道对方的 MAC 地址,两者也不能直接通信,必须经过三层路由转发才可以。所以此时,源主机通过 ARP 协议获得的将不是目的主机的真实 MAC 地址,而是一台可以通往局域网外的路由器的 MAC 地址。于是此后源主机发往目的主机的所有帧,都将发往该路由器,通过它向外发送。这种情况称为委托 ARP 或 ARP 代理(Proxy)。

ARP spoofing(欺骗)
ARP机制是一种 “无状态”、“无验证” 的协议,所以它很容易受到 ARP spoofing 攻击。ARP spoofing,即 ARP 欺骗,又称 ARP 投毒,是一种针对 ARP 的攻击方式。
ARP 欺骗的运作原理是由攻击者发送假的 ARP 数据包到网络上,尤其是送到网关上。假设你的网关的 IP 地址是 192.168.0.2,MAC 地址为 00-11-22-33-44-55,那么你发送的数据都会从这个 MAC 地址经过,这时候我发送大量的 ARP 数据包,然而我的包是构造出来的,IP 依旧是你的 IP,但 MAC 地址却被我替换成了我的 MAC 地址。此时当你更新你的 ARP 缓存时,就会把我机器的 MAC 地址当成 192.168.0.2 的 MAC 地址,于是你的流量都到我这来了。
所以 ARP 欺骗的目的是要让送至特定的 IP 地址的流量被错误送到攻击者所取代的地方。因此攻击者可将这些流量另行转送到真正的网关(Passive Sniffing,被动式数据包嗅探)或是篡改后再转送(Man-in-the-middle Attack,中间人攻击)。攻击者亦可将 ARP 数据包导到不存在的 MAC 地址以达到阻断服务攻击的效果。
最理想的预防方式就是使用静态的 ARP 条目,对于网关:将所有的客户端的 MAC 以及对应 IP 进行静态绑定,防止攻击者假冒客户端。而对于普通客户端:绑定网关 MAC 地址,防止攻击者假冒网关;不过在大型网络不可行,因为 ARP 经常需要更新,另外一种方法,例如:DHCP snooping,网络设备可借由 DHCP 保留网络上各电脑的 MAC 地址,在伪造的 ARP 数据包发出时即可侦测到。此方式已在一些厂牌的网络设备产品所支持。
实验环境:两台电脑同处于一个局域网下,我的电脑IP地址是10.102.38.182,另外一台点脑ip地址是10.102.40.125
用我的电脑ping另外一台电脑,使用wireshark抓包
请求报文如下:

响应报文如下:

ARP
链路层通信根据48bit以太网地址(硬件地址)来确定目的接口,而地址解析协议负责32bit IP地址与48bit以太网地址之间的映射:
- (1)ARP负责将IP地址映射到对应的硬件地址
- (2)RARP负责相反的过程,通常用于无盘系统。
ARP高速缓存
ARP高效运行的关键是每台主机上都有一个ARP高速缓存,缓存中每一项的生存时间一般为20分钟,但不完整表项超时时间一般为3分钟(如192.168.13.254)。
# arp -a
? (192.168.0.16) at 00:1b:21:b9:9f:d4 [ether] on eth0
? (192.168.0.6) at 00:1b:21:b9:9f:d4 [ether] on eth0
? (192.168.13.233) at 00:16:3e:01:7a:b2 [ether] on eth0
? (192.168.13.254) at <incomplete> on eth0
可以通过arp命令来操作ARP高速缓存:
- arp 显示当前的ARP缓存列表。
- arp -s ip mac 添加静态ARP记录,若需要永久保存,应该编辑/etc/ethers文件。
- arp -f 使/etc/ethers中的静态ARP记录生效。
ARP分组格式

其中:
- ARP协议的帧类型为0x0806
- 硬件类型:1表示以太网地址
- 协议类型:0x800表示IP协议
- 硬件地址长度:值为6
- 协议地址长度:值为4
- op:1为ARP请求,2为ARP应答,3为RARP请求,4为RARP应答
- 对于ARP请求来说,目的端硬件地址为广播地址f:ff:ff:ff:ff:ff),由ARP相应的主机填入。
一个完整ARP请求应答的抓包:
# tcpdump -e -p arp -n -vv
21:08:10.329163 00:16:3e:01:79:43 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.14.23 tell 192.168.13.43, length 28
21:08:10.329626 00:16:3e:01:7b:17 > 00:16:3e:01:79:43, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 192.168.14.23 is-at 00:16:3e:01:7b:17, length 46
ARP代理
当向位于不同网络的主机发送ARP请求时,由两个网络之间的路由器响应该ARP请求,这个过程称为ARP代理。
ARP代理也称为混合ARP:通过两个网络之间的路由器可以互相隐藏物理网络。
免费ARP
主机发送ARP请求查找自己的IP地址。通常有两个用途:
- (1)确认网络中是否有其他主机设置了相同的IP地址;
- (2)当主机的物理地址改变了,可以通过免费ARP更新更新路由器和其他主机中的高速缓存。
RARP
- RARP通常用于无盘系统,无盘系统从物理网卡上读到硬件地址后,发送一个RARP请求查询自己的IP地址。
- RARP的协议格式:与ARP协议一致,只不过帧类型代码为0x8035
- RARP使用链路层广播,这样阻止了大多数路由器转发ARAP请求,只返回很小的信息,即IP地址。