4TCP/IP详解(卷1:协议)

ARP

地址解析协议

ARP请求ARP响应ARP缓存

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第4章:ARP(Address Resolution Protocol)

地址解析协议

一、导读

1.1 本章学习目标

第4章深入讲解ARP(地址解析协议)——TCP/IP协议栈中连接网络层和链路层的关键桥梁。当一台主机需要向同一局域网内的另一台主机发送IP数据报时,它必须知道目的主机的MAC地址才能在链路层封装帧。ARP负责将IP地址"解析"为MAC地址,是局域网通信不可或缺的基础协议。

本章的核心学习目标包括:

  • 理解ARP的基本工作原理:请求广播、响应单播、缓存管理
  • 掌握ARP报文的格式:硬件类型、协议类型、操作码、地址字段
  • 理解ARP缓存的生命周期:创建、更新、超时删除
  • 掌握跨子网通信时ARP的行为:ARP解析的是下一跳路由器的MAC地址,而非最终目的地的MAC地址
  • 了解ARP的高级特性: gratuitous ARP、proxy ARP、ARP欺骗
  • 学会使用工具观察和分析ARP行为:arp命令、tcpdump抓包分析

1.2 为什么本章如此重要

ARP是IP协议能够正常工作的基础。没有ARP,IP数据报就无法封装成链路层帧,因为发送方不知道目的MAC地址。虽然ARP协议本身非常简单(只有请求和响应两种报文),但它在实际网络中的行为却有很多值得深入理解的细节。

理解ARP对于网络故障排查至关重要。很多"网络不通"的问题,根源在于ARP解析失败:IP地址配置错误导致跨子网但ARP试图在本地解析、MAC地址冲突导致ARP缓存混乱、交换机端口安全策略阻止了ARP广播等。此外,ARP欺骗是一种常见的局域网攻击手段,理解ARP的安全缺陷是防范此类攻击的前提。

1.3 核心问题引导

在阅读本章时,请带着以下问题思考:

为什么IP地址不能直接用于链路层传输?为什么需要MAC地址?

ARP请求为什么使用广播而不是单播?这有什么优缺点?

当目的主机不在同一子网时,ARP解析的是谁的MAC地址?为什么?

ARP缓存为什么需要超时机制?如果没有超时会出什么问题?

ARP欺骗是如何实现的?为什么ARP协议容易被攻击?

gratuitous ARP有什么用途?它在什么场景下使用?


二、核心概念详解

2.1 ARP的基本工作原理

ARP的核心功能非常简单:给定一个IP地址,找到对应的MAC地址。

2.1.1 ARP解析过程

假设主机A(192.168.1.100,MAC: 00:11:22:33:44:55)需要向同子网的主机B(192.168.1.200)发送IP数据报:

步骤1:主机A检查自己的ARP缓存,查找是否有192.168.1.200的MAC地址映射。

步骤2:如果缓存未命中,主机A构造一个ARP请求报文,以广播方式发送:

ARP请求:
  操作码:1(请求)
  发送方MAC:00:11:22:33:44:55
  发送方IP:192.168.1.100
  目标MAC:00:00:00:00:00:00(未知,填空)
  目标IP:192.168.1.200

这个ARP请求封装在以太网帧中,目的MAC为 FF:FF:FF:FF:FF:FF(广播地址)。

步骤3:子网中的所有主机都会收到这个广播帧。每台主机检查ARP请求中的目标IP是否匹配自己的IP地址。

步骤4:主机B(192.168.1.200,MAC: 66:77:88:99:AA:BB)发现目标IP匹配,向主机A发送ARP响应(单播):

ARP响应:
  操作码:2(响应)
  发送方MAC:66:77:88:99:AA:BB
  发送方IP:192.168.1.200
  目标MAC:00:11:22:33:44:55
  目标IP:192.168.1.100

步骤5:主机A收到响应后,将IP-MAC映射存入ARP缓存,然后就可以正常发送IP数据报了。

2.2 ARP报文格式

ARP报文封装在以太网帧的数据部分,类型字段为0x0806。

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          硬件类型(16)          |          协议类型(16)          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   硬件地址长度 |   协议地址长度 |          操作码(16)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    发送方硬件地址(可变长)                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    发送方协议地址(可变长)                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    目标硬件地址(可变长)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    目标协议地址(可变长)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

对于以太网+IPv4的场景:

  • 硬件类型 = 1(以太网)
  • 协议类型 = 0x0800(IPv4)
  • 硬件地址长度 = 6(MAC地址6字节)
  • 协议地址长度 = 4(IPv4地址4字节)
  • ARP报文总长度 = 28字节

2.3 ARP缓存管理

每台主机都维护一个ARP缓存表,存储最近的IP-MAC映射,避免每次通信都需要广播ARP请求。

2.3.1 缓存条目状态

ARP缓存条目通常有以下状态:

状态说明
INCOMPLETE已发送ARP请求,等待响应
REACHABLE已确认可达(收到响应)
STALE可达但可能过期(超过一定时间未使用)
DELAY等待确认是否仍然可达
PROBE正在发送确认请求
FAILED解析失败

2.3.2 缓存超时

ARP缓存条目有超时时间(通常20分钟)。超时后,条目被标记为STALE。下次使用该条目时,系统会发送一个单播ARP请求来确认映射是否仍然有效。

bash
# Linux查看ARP缓存
ip neigh show
# 192.168.1.200 dev eth0 lladdr 66:77:88:99:aa:bb REACHABLE
# 192.168.1.1 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE

# 添加静态ARP条目(不会超时)
sudo arp -s 192.168.1.200 66:77:88:99:AA:BB

# 删除ARP条目
sudo ip neigh flush dev eth0

2.4 跨子网通信与ARP

当目的主机不在同一子网时,源主机将数据报发送给默认网关(路由器)。此时,ARP解析的是路由器的MAC地址,而不是最终目的地的MAC地址。

主机A (192.168.1.100)                     路由器              主机B (10.0.0.100)
     │                                     │                     │
     │  ARP请求:192.168.1.1的MAC?        │                     │
     │ ──────────────────────────────────→ │                     │
     │                                     │                     │
     │  ARP响应:我是192.168.1.1,         │                     │
     │  MAC是aa:bb:cc:dd:ee:ff             │                     │
     │ ←────────────────────────────────── │                     │
     │                                     │                     │
     │  IP数据报:src=192.168.1.100        │                     │
     │  dst=10.0.0.100                     │  IP数据报转发        │
     │  帧:dst MAC=aa:bb:cc:dd:ee:ff      │ ──────────────────→ │
     │ ──────────────────────────────────→ │                     │

关键点:

  • IP数据报的目的IP始终是最终目的地(10.0.0.100),全程不变
  • 链路层帧的目的MAC是下一跳的MAC地址,每一跳都会改变
  • 源主机ARP解析的是默认网关的MAC地址,不是最终目的地的MAC地址

2.5 ARP的高级特性

2.5.1 Gratuitous ARP(免费ARP)

Gratuitous ARP是主机主动广播的ARP请求,用于宣告自己的IP-MAC映射。它不询问任何信息,只是通知网络中的其他设备。

用途:

  • IP地址冲突检测:主机配置IP地址后,发送gratuitous ARP,如果有其他主机响应相同的IP,说明地址冲突
  • 更新其他设备的ARP缓存:当主机的MAC地址改变时(如网卡更换),发送gratuitous ARP通知其他设备更新缓存

2.5.2 Proxy ARP(代理ARP)

Proxy ARP允许路由器代替其他子网的主机响应ARP请求。当主机发送ARP请求查询一个不在本子网的IP地址时,路由器用自己的MAC地址响应,然后在收到数据报后进行路由转发。

这种技术可以让不支持路由配置的主机与远程子网通信,但现代网络中很少使用,因为默认网关配置更加高效。

2.5.3 ARP欺骗(ARP Spoofing)

ARP协议没有认证机制——任何主机都可以发送ARP响应,接收方会无条件接受并更新ARP缓存。这个安全缺陷被ARP欺骗攻击利用:

攻击者 (192.168.1.50, MAC: evil:evil:evil)
  │
  │  向主机A发送伪造的ARP响应:
  │  "192.168.1.1(网关)的MAC是 evil:evil:evil"
  │ ──────────────────────────────────→ 主机A
  │
  │  向网关发送伪造的ARP响应:
  │  "192.168.1.100(主机A)的MAC是 evil:evil:evil"
  │ ──────────────────────────────────→ 网关

此后,主机A发往网关的数据报都会被发送到攻击者的机器。攻击者可以:

  • 窃听:转发数据报(充当中间人),同时记录所有流量
  • 篡改:修改数据报内容后再转发
  • 拒绝服务:丢弃数据报,中断通信

防范措施:

  • 使用静态ARP条目(不适合大规模网络)
  • 使用Dynamic ARP Inspection(DAI,交换机安全特性)
  • 使用ARP防火墙工具

三、实战案例

3.1 案例一:使用tcpdump观察ARP请求和响应

bash
sudo tcpdump -i eth0 -nn -e 'arp'

输出示例:

12:34:56.789 00:11:22:33:44:55 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806),
  length 42: arp who-has 192.168.1.200 tell 192.168.1.100

12:34:56.790 66:77:88:99:aa:bb > 00:11:22:33:44:55, ethertype ARP (0x0806),
  length 42: arp reply 192.168.1.200 is-at 66:77:88:99:aa:bb

分析:

  • 第一行:ARP请求,广播帧(目的MAC为ff:ff:ff:ff:ff:ff),询问192.168.1.200的MAC地址
  • 第二行:ARP响应,单播帧(目的MAC为请求方的MAC),回答192.168.1.200的MAC地址

3.2 案例二:观察跨子网通信的ARP行为

bash
# 主机A ping 远程子网的主机B
ping 10.0.0.100

# 同时抓包
sudo tcpdump -i eth0 -nn -e 'arp or icmp'

输出示例:

12:34:56.789 00:11:22:33:44:55 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806),
  length 42: arp who-has 192.168.1.1 tell 192.168.1.100
  ↑ 注意:ARP解析的是网关192.168.1.1的MAC,不是10.0.0.100

12:34:56.790 aa:bb:cc:dd:ee:ff > 00:11:22:33:44:55, ethertype ARP (0x0806),
  length 42: arp reply 192.168.1.1 is-at aa:bb:cc:dd:ee:ff

12:34:56.791 00:11:22:33:44:55 > aa:bb:cc:dd:ee:ff, ethertype IPv4 (0x0800),
  length 98: 192.168.1.100 > 10.0.0.100: ICMP echo request
  ↑ IP数据报的目的IP是10.0.0.100,但帧的目的MAC是网关aa:bb:cc:dd:ee:ff

3.3 案例三:使用arping工具

bash
# arping结合了ping和ARP的功能,在链路层测试主机是否可达
arping -I eth0 192.168.1.200
# ARPING 192.168.1.200
# 64 bytes from 66:77:88:99:aa:bb (192.168.1.200): index=0 time=1.234 msec
# 64 bytes from 66:77:88:99:aa:bb (192.168.1.200): index=1 time=0.987 msec

四、常见误区与难点

4.1 误区一:"ARP解析的是最终目的地的MAC地址"

当目的主机不在同一子网时,ARP解析的是默认网关(路由器)的MAC地址,不是最终目的地的MAC地址。IP数据报的目的IP始终是最终目的地,但链路层帧的目的MAC是下一跳的MAC。

4.2 误区二:"ARP是网络层协议"

ARP的层级归属有争议。它为IP服务(解析IP到MAC的映射),但ARP报文直接封装在以太网帧中,不经过IP层。Stevens将其放在链路层讨论。关键理解:ARP是链路层和网络层之间的桥梁。

4.3 难点:理解 gratuitous ARP 和 IP 地址冲突检测

当主机启动时,它会发送一个 gratuitous ARP(ARP请求中目标IP是自己的IP),如果收到响应,说明IP地址已被使用。这个机制简单但有效。


五、本章小结

第4章深入讲解了ARP协议:

ARP将IP地址解析为MAC地址,是局域网通信的基础。请求使用广播,响应使用单播。

ARP缓存避免了每次通信都需要广播请求,但条目有超时时间(通常20分钟)。

跨子网通信时,ARP解析的是默认网关的MAC地址,而非最终目的地的MAC地址。

ARP没有认证机制,容易被ARP欺骗攻击利用。防范措施包括静态ARP、DAI等。

gratuitous ARP用于IP地址冲突检测和缓存更新。


六、思考与练习

思考题

如果ARP缓存的超时时间设为无限长(永不超时),会带来什么问题?

为什么ARP请求使用广播而ARP响应使用单播?如果ARP响应也使用广播,会有什么影响?

在一个有1000台主机的局域网中,ARP广播会不会造成严重的网络负担?如何优化?

如果一台主机同时连接了两个不同的子网(两个网卡),ARP行为会有什么不同?

练习题

使用tcpdump捕获一次完整的ARP请求和响应过程,记录报文的每个字段值。

使用 ip neigh 查看ARP缓存,然后ping一个不存在的主机,观察ARP缓存的变化。

编写一个简单的程序,使用原始套接字构造并发送ARP请求报文,监听ARP响应。

4/13ARP
0%