ARP 协议详解
ARP(Address Resolution Protocol,地址解析协议)是TCP/IP协议族中的链路层协议,用于在局域网内将IP地址解析为MAC地址,实现不同网络层协议和链路层协议之间的地址映射。
1. ARP 协议概述
基本概念
作用 :IP地址到MAC地址的动态映射
协议层 :链路层(OSI第2层)
封装 :以太网帧(EtherType=0x0806)
工作范围 :同一广播域(局域网段)
动态学习 :通过广播查询和单播响应建立映射
ARP 工作原理
1. 发送方需要发送IP数据包到目标IP
2. 检查本地ARP缓存,无匹配则广播ARP请求
3. 目标主机响应ARP回复(单播)
4. 发送方更新ARP缓存,封装MAC地址发送数据
ARP 消息类型
类型 说明 ARP Request 广播请求:谁有此IP? ARP Reply 单播响应:我是此IP,MAC地址是… RARP Request/Reply 反向地址解析(已废弃) InARP 反向ARP(ATM/FR网络)
2. ARP 报文格式
以太网封装的ARP报文
以太网头部 (14字节)
+-----------------------------------+
| 目的MAC (6B,全FF广播) | 源MAC (6B) |
+-----------------------+-----------+
| 类型 (2B: 0x0806 ARP) |
+-----------------------------------+
ARP数据 (28字节)
+-----------------------------------+
| 硬件类型(2B)|协议类型(2B)|硬件长度|协议长度|
+-------------+------------+--------+---------+
| 操作码(2B) | 源MAC(6B) | 源IP(4B) |
+-------------+------------+--------+---------+
| 目标MAC(6B) | 目标IP(4B) |
+-------------+------------+----------------+
字段详解
字段 大小 值 说明 硬件类型 2字节 1 以太网(其他:Token Ring=6,FDDI=15) 协议类型 2字节 0x0800 IPv4(IPv6=0x86DD) 硬件地址长度 1字节 6 MAC地址长度 协议地址长度 1字节 4 IPv4地址长度 操作码 2字节 1/2 1=请求,2=响应 源/目标MAC 6字节 – 物理地址 源/目标IP 4字节 – 逻辑地址
ARP 请求示例(十六进制)
ARP Request: who has 192.168.1.100?
FF:FF:FF:FF:FF:FF 00:11:22:33:44:55 08:06
00:01 08:00 06:04 00:01 00:11:22:33:44:55 C0:A8:01:64 00:00:00:00:00:00 00:00:00:00
└广播MAC └源MAC └源IP(192.168.1.100) └目标MAC(全0) └目标IP(全0)
ARP 响应示例
ARP Reply: 192.168.1.100 is at AA:BB:CC:DD:EE:FF
00:11:22:33:44:55 AA:BB:CC:DD:EE:FF 08:06
00:01 08:00 06:04 00:02 AA:BB:CC:DD:EE:FF C0:A8:01:64 00:11:22:33:44:55 C0:A8:01:10
└目标MAC └源MAC └源IP └目标MAC └目标IP
3. ARP 缓存机制
ARP 缓存表
# Linux查看ARP表
arp -a
# 或
ip neigh show
# 示例输出
? (192.168.1.1) at 00:50:56:c0:00:01 [ether] on eth0
192.168.1.100 at aa:bb:cc:dd:ee:ff [ether] on eth0
# Windows
arp -a
缓存条目状态
状态 说明 INCOMPLETE ARP请求已发送,等待响应 REACHABLE 最近有通信,活跃 STALE 过期但可用 DELAY 延迟确认 PROBE 主动探测有效性
缓存管理
超时时间 :通常几分钟到几小时
动态学习 :自动从ARP响应更新
静态条目 :手动配置,永不过期
刷新机制 :定期或通信时更新
# 添加静态ARP条目
arp -s 192.168.1.100 aa:bb:cc:dd:ee:ff
# 删除条目
arp -d 192.168.1.100
# Linux邻居表管理
ip neigh add 192.168.1.100 lladdr aa:bb:cc:dd:ee:ff dev eth0
ip neigh del 192.168.1.100 dev eth0
4. ARP 工作流程详解
ARP 请求和响应流程
主机A (192.168.1.10) → 目标 192.168.1.100
1. A检查ARP缓存,无192.168.1.100条目
2. A构建ARP请求:
- 源IP/MAC: 192.168.1.10 / 00:11:22:33:44:55
- 目标IP: 192.168.1.100,目标MAC: 00:00:00:00:00:00
- 操作码: 1 (请求)
3. A广播ARP请求 (目的MAC: FF:FF:FF:FF:FF:FF)
4. 网络中所有主机接收广播
5. 主机B (192.168.1.100) 匹配目标IP
6. B构建ARP响应:
- 源IP/MAC: 192.168.1.100 / AA:BB:CC:DD:EE:FF
- 目标IP/MAC: 192.168.1.10 / 00:11:22:33:44:55
- 操作码: 2 (响应)
7. B单播响应给A
8. A更新ARP缓存,发送原始IP数据包
免费ARP(Gratuitous ARP)
目的 :IP冲突检测,MAC地址更新
特点 :源IP=目标IP,广播发送
场景 :
主机启动时检测IP冲突
MAC地址变更通知
DHCP IP分配确认
# Linux发送免费ARP
ping -b 192.168.1.255 -c 1 192.168.1.10 # 源IP=目标IP
arping -U -I eth0 192.168.1.10 # 用户态ARP
5. ARP 协议变种
RARP(Reverse ARP,已废弃)
作用 :MAC地址到IP地址解析
场景 :无盘工作站启动
问题 :广播开销大,安全性差
替代 :BOOTP → DHCP
InARP(Inverse ARP)
作用 :ATM/Frame Relay中的DLCI到IP映射
场景 :非广播多路访问网络
报文 :类似ARP但操作码不同
GARP(Gratuitous ARP)
免费ARP的标准化名称,用于:
6. 代理ARP(Proxy ARP)
工作原理
主机A (192.168.1.10/24) → 路由器 → 主机B (192.168.2.10/24)
1. A发送ARP请求寻找192.168.2.10
2. 路由器收到广播,检查路由表
3. 路由器知道192.168.2.0/24网络
4. 路由器用自身MAC响应ARP
5. A将数据包发给路由器MAC
6. 路由器转发到正确网络
配置示例
# Linux启用代理ARP
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
# Cisco路由器
interface Ethernet0/0
ip address 192.168.1.1 255.255.255.0
ip proxy-arp
# 检查代理ARP表
ip neigh show proxy
应用场景
无路由配置 :简化终端配置
网段扩展 :透明二层扩展
VPN网关 :连接远程网络
7. ARP 安全威胁和防护
ARP 欺骗/投毒(ARP Spoofing/Poisoning)
攻击者 → 发送虚假ARP响应
受害者ARP缓存 → 攻击者MAC代替网关MAC
数据流量 → 重定向到攻击者 → 中间人攻击
攻击流程
# 使用arpspoof工具
arpspoof -i eth0 -t 192.168.1.100 192.168.1.1 # 欺骗主机指向攻击者
arpspoof -i eth0 -t 192.168.1.1 192.168.1.100 # 欺骗网关指向攻击者
# 同时运行:流量双向劫持
防护措施
1. 静态ARP条目
arp -s 192.168.1.1 00:50:56:c0:00:01 # 网关静态绑定
2. 动态ARP检查(DAI)
# Cisco交换机
ip arp inspection vlan 10
ip arp inspection validate src-mac dst-mac ip
!
interface range GigabitEthernet1/0/1 - 48
ip arp inspection trust # 信任端口(连接路由器)
3. 端口安全
# 限制MAC地址数量
switchport port-security maximum 2
switchport port-security violation restrict
switchport port-security mac-address sticky
4. ARP 监视工具
# arpwatch监控ARP变化
arpwatch -i eth0
# arp-scan扫描网络
sudo arp-scan --localnet
# 配置告警
# /etc/arpwatch.conf
eth0 log
8. 编程实现
Python Scapy 发送ARP
from scapy.all import *
# ARP请求
arp_request = ARP(pdst="192.168.1.100")
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_packet = broadcast/arp_request
answer = srp(arp_packet, timeout=2, verbose=0)[0]
# 响应解析
for sent, received in answer:
print(f"IP {received.psrc} MAC {received.hwsrc}")
# 免费ARP
gratuitous = ARP(hwsrc=get_if_hwaddr("eth0"), psrc="192.168.1.10",
pdst="192.168.1.10", op=1)
sendp(Ether(dst="ff:ff:ff:ff:ff:ff")/gratuitous, iface="eth0")
# ARP欺骗(仅测试环境)
def arp_spoof(target_ip, gateway_ip):
target_mac = getmacbyip(target_ip)
pkt = ARP(op=2, pdst=target_ip, hwdst=target_mac,
psrc=gateway_ip)
send(pkt, verbose=0)
C语言原始套接字ARP
#include <net/if.h>
#include <netinet/if_ether.h>
#include <sys/socket.h>
#include <arpa/inet.h>
struct arphdr {
unsigned short ar_hrd; // 硬件类型
unsigned short ar_pro; // 协议类型
unsigned char ar_hln; // 硬件地址长度
unsigned char ar_pln; // 协议地址长度
unsigned short ar_op; // 操作码
// 源硬件地址 + 源协议地址
// 目标硬件地址 + 目标协议地址
};
void send_arp_request(int sock, struct in_addr src_ip, uint8_t* src_mac) {
struct arphdr arp;
struct ether_header eth;
// 以太网头部
memset(ð, 0, sizeof(eth));
memcpy(eth.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6);
memcpy(eth.ether_shost, src_mac, 6);
eth.ether_type = htons(ETHERTYPE_ARP);
// ARP头部
arp.ar_hrd = htons(ARPHRD_ETHER);
arp.ar_pro = htons(ETHERTYPE_IP);
arp.ar_hln = 6;
arp.ar_pln = 4;
arp.ar_op = htons(ARPOP_REQUEST);
// 构建完整数据包并发送...
}
9. 网络诊断和工具
常用工具
# ARP表查看
arp -a -n
ip neigh show
# ARP扫描
arp-scan --localnet --interface=eth0
nmap -sn 192.168.1.0/24 # ping扫描
# ARP监控
arpwatch -i eth0 -f /var/log/arpwatch.log
# 抓包分析
tcpdump -i eth0 -e arp -n
wireshark filter: arp
# 测试连通性
arping -I eth0 -c 3 192.168.1.100
抓包分析
# 捕获ARP流量
tcpdump -i eth0 -n -e arp -w arp.pcap
# 分析ARP欺骗
tcpdump -r arp.pcap -n 'arp[20:2] == 0x0002 and arp[8:4] == 0xc0a80101'
# 查找重复IP响应
日志告警配置
# /etc/syslog.conf
local0.* /var/log/arpwatch/arpwatch.log
# 邮件告警
arpwatch -i eth0 -m admin@example.com
10. 高级配置和优化
ARP 过滤规则
# iptables ARP过滤
iptables -t mangle -A PREROUTING -p arp --arp-mac-source ! 00:11:22:33:44:55 -j DROP
# ebtables(桥接过滤)
ebtables -A INPUT -p ARP --arp-mac-src ! 00:11:22:33:44:55 -j DROP
大型网络优化
# 调整ARP缓存大小
echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
# 代理ARP配置
sysctl -w net.ipv4.conf.eth0.proxy_arp=1
VLAN环境配置
# 每个VLAN独立ARP表
ip neigh add 192.168.10.1 lladdr 00:50:56:c0:00:01 dev vlan10
ip neigh add 192.168.20.1 lladdr 00:50:56:c0:00:02 dev vlan20
11. 故障排除
常见问题
问题 原因 解决方法 ARP不响应 防火墙阻止 检查iptables/ebtables规则 ARP缓存错误 欺骗攻击 启用DAI,静态条目 大量广播 ARP风暴 限制广播域,STP配置 IP冲突 重复配置 免费ARP检测,IPAM系统 邻居不可达 链路问题 检查物理连接,VLAN配置
诊断步骤
1. 检查ARP表:arp -a
2. 测试连通性:ping -c 3 192.168.1.100
3. 抓包分析:tcpdump -i eth0 arp
4. 检查交换机:show mac address-table
5. 验证路由:ip route get 192.168.1.100
性能监控
# ARP统计
cat /proc/net/arp
netstat -s | grep -i arp
# 实时监控
watch -n 1 "arp -a && echo '---'"
12. IPv6 中的邻居发现协议(NDP)
NDP vs ARP
特性 ARP (IPv4) NDP (IPv6) 封装 以太网帧 ICMPv6 认证 无 可选IPsec 双向发现 单向 邻居和路由器发现 地址自动配置 无 SLAAC 安全性 易欺骗 SEND扩展
NDP 消息类型
路由器通告(RA) :网络前缀配置
路由器征求(RS) :请求RA
邻居征求(NS) :类似ARP请求
邻居通告(NA) :类似ARP响应
ARP协议作为局域网地址解析的核心,通过广播查询和缓存机制实现了高效的IP-MAC映射。虽然简单有效,但其无认证特性使其易受欺骗攻击。现代网络通过静态条目、DAI、端口安全等措施增强ARP安全性,是构建可靠局域网的基础协议。