地址解析协议(Address Resolution Protocol,ARP):ARP协议可以将IPv4地址(一种逻辑地址)转换为各种网络所需的硬件地址(一种物理地址)。换句话说,所谓的地址解析的目标就是发现逻辑地址与物理地址的映射关系。 ARP仅用于IPv4协议,IPv6使用邻居发现协议(NDP)替代。
ARP协议目前最广泛应用于寻找32位IPv4地址与以太网的48位MAC地址之间的映射。
掌握ARP协议前,需要理解什么是逻辑地址和物理地址。
物理地址:物理地址对于主机就类似身份证对于人类。对于每个网络适配器,设置制造商都会给定一个永久的物理地址,将其存储在设备的永久性内存中。就像身份证一样,物理地址就是网络适配器的ID。注意,物理地址是和网络适配器绑定的,如果主机更换了网络适配器,那么它的物理地址也会相应改变。(虽然网络适配器的物理地址是固定的,但也可以通过特殊方法修改,但这种情况极少出现,不影响我们理解)
在TCP/IP分层体系结构中,数据链路层和物理层使用的地址是物理地址。而网络层、传输层和应用层使用的地址是IP地址(逻辑地址)。
逻辑地址:逻辑地址就是我们常说的IP地址,因为IP地址是由软件实现的,所以把它称为逻辑地址。IP地址是不固定的,它通常从某个网络的IP地址池中获得,改变网络环境,IP地址就会改变。
分组进行传输必须要2级地址:逻辑地址和物理地址。
IP地址和物理地址是在不同的层次下运行的。同一个目的IP地址可能经过多段链路,每段链路都可能运行不同的链路层和物理层协议,它们的物理地址格式可能都截然不同;同理,同一段链路可能接收来自不同的网络层协议,比如IPv4或者IPX。
有人可能觉得,直接用物理地址替代IP地址不就行了么?
这是因为对IP地址不够了解。现实中,有很多链路层和物理层的协议,它们都有不同的物理地址。如果完全依赖物理地址,那么路由表就需要对每个物理地址建立一个项,那样没有一个路由器能够负担如此庞大的表项。
而IP地址提供了更高层次的抽象,将不同的物理地址抽象为统一的逻辑地址。
IP地址有良好的分层。如果分组转发到同一子网,只需要在路由表中记录统一的网络前缀。比如,一个子网有6000个IP地址,对应6000个物理地址。记录IP地址网络前缀只需要1行,记录物理地址则需要6000行。
有了IP地址,分组的路由(也就是找路)的工作仿佛在同一个网络中进行。如果传输IPv4分组,那么IPv4分组传输过程中经过的所有网络都使用IPv4协议,仿佛它们在一个逻辑上的网络中。
ARP协议主要依赖ARP高速缓存(ARP cache)。ARP高速缓存就是一个映射表,它记录了IP地址和物理地址的映射关系。每一台主机和路由器都设有ARP高速缓存,在实际传输中,通常已知下一跳的目的IP地址(这是通过查询路由表完成的,不是本篇的知识),通过查询ARP高速缓存即可知道对应的物理地址。
高速缓存记录的映射表不是一开始就有的。假设已知下一跳的目的IP地址,如何通过ARP协议得知下一跳对应的物理地址呢?
答案是通过广播ARP请求分组。
ARP请求分组有3个重要信息:1.源IP地址。2.对应的源物理地址。3.目的IP地址。
查询的内容为:对应的目的物理地址。
以下是具体步骤:
源主机或者路由器会给该网络的所有主机发送ARP请求分组(也就是给这个网络广播该分组),所有主机会检查分组的目的IP地址是否与自身的IP地址相同。如果不相同,就丢弃该分组;如果相同,就说明自己就是被寻找的目的主机或者路由器。
目的主机(或目的路由器)在收到ARP请求分组后,会做两件事:
1.将源主机的IP地址和对应的物理地址添加进自身的ARP高速缓存映射表。
这是因为既然源主机会和自己通信,那么自己之后也可能会主动和源主机通信,提前建立源主机的映射表项是有必要的,之后自己要主动和源主机通信就不用广播ARP请求分组了。
2.给源主机发送ARP响应报文(注意,该报文是单播的)
目的主机需要给源主机发送ARP响应报文,告知源主机自己的物理地址。源主机在收到所需的ARP响应报文,就可以发送帧给目的主机了。
为什么是单播而不是广播呢?那是因为目的主机已经有源主机的物理地址了,可以直接给源主机发送对应的帧,不需要广播。
当源主机接收到ARP响应报文后,也会将目的主机的IP地址和对应的物理地址添加到自己的ARP高速缓存映射表中,这样下次再和该主机通信,就不用广播ARP分组了。之后就可以通过物理地址,给目的主机发送帧了。
ARP协议是在单个网络内部运行的。如果源主机和目的主机不在一个网络中,必须多次使用ARP协议。
无论情况多复杂,都是由以下4种情况组合而成的。
如果源主机和目的主机在一个网络中,这就很简单,源主机直接通过ARP协议寻找目的主机的物理地址。
也就是情况1:源主机直接通过ARP协议寻找同一个网络下目的主机的物理地址。
如果源主机和目的主机不在一个网络中,就必须通过路由器路由。通过查找路由表,将目的主机的IP地址转换为下一跳的IP地址。再通过ARP协议,将下一跳的IP地址转换为对应的物理地址。
细分有3种情况:
情况2:源主机寻找下一跳路由器的物理地址。
情况3:路由器寻找在同一个网络中的目的主机的物理地址。
情况4:路由器和目的主机不在同一个网络中,路由器A寻找下一条路由器B的物理地址。
其实这4种情况非常好理解,只需要理解路由表的作用和ARP映射表的作用即可。
ARP高速缓存是动态的,而且缓存记录的映射项有生存周期,一般默认是20分钟。超过生存周期,那条映射就会从映射表中移除。
为什么需要设置生存周期呢?
是因为物理地址和IP地址都可能改变。比如目的主机更换了网络适配器,那么目的主机的物理地址就改变了。
如果源主机通过查看ARP映射表得到了目的主机以前的物理地址,肯定是无法正常通信的。但随着该表项生存周期到时,源主机会重新广播ARP请求分组,这样就可以得到目的主机新的物理地址。从而和目的主机正常通信。
ARP协议是很特殊的协议,它像是介于网络层和链路层之间的协议。
ARP协议是封装在帧中的,就像IPv4协议封装在以太网帧一样,从这个角度讲,ARP协议像网络层协议。
但是ARP协议是为网络层协议服务的,从服务的角度讲,它又像链路层协议。
实际中,ARP协议常封装在以太网帧中。
当广播ARP请求分组时,该网络中的所有主机都会从以太网帧中提取出ARP协议分组,检查接收方协议地址字段,如果和自身IP地址不相同,就丢弃该分组。如果相同,说明自身的物理地址就是被寻找的地址。就需要给发送方回复ARP响应分组(通过单播)。
ARP的响应报文会将发送方硬件地址字段和发送方协议地址字段填写成自身的物理地址和IP地址。将接收方硬件地址和接收方协议地址填写为ARP请求报文的发送方硬件地址和发送方协议地址。
从上图可知,ARP协议被封装在Ethernet协议(以太网协议)中。
我们先看Ethernet II部分:
Destination(目的物理地址)字段的值为:ff:ff:ff:ff:ff:ff
说明该以太网帧是广播帧,和ARP请求分组是通过广播形式发送吻合。
Source(源物理地址)字段的值为:50:eb:f6:56:ca:57
这是发送方主机的物理地址,和ARP协议的Sender MAC address字段的值完全吻合。
Type字段为:ARP(0x0806)。
说明该以太网帧封装的是一个ARP协议分组。
再看ARP协议部分:
前4个字段表明物理地址和逻辑地址的类型和长度,和之前讲解的吻合。
第五个字段Opcode的值为1,说明是ARP请求报文。
后面4个字段是源物理地址和IP地址,以及目标物理地址和IP地址。
值得注意的是,目标物理地址正如之前所说,全部填充的0。因为该字段正是ARP请求报文需要获取的,目前不知,只能全部填充为0。
先看Ethernet II部分:
Destination(目的物理地址)字段的值正好是ARP请求报文的Source字段的值。
也就是说,该ARP响应报文是用来回应之前的ARP请求分组的。
该值也和Target MAC address的值相同。
Source(源物理地址)字段的值为目的端的物理地址,该值和Sender MAC address的值相同。
Padding是填充字段,用来填充以太网帧到最小帧长。
再看ARP协议部分:
前4个字段没什么好讲的。
第五个字段Opcode为2,表示这是ARP响应分组。
后面4个字段,源MAC地址正是ARP请求报文想寻找的物理地址。源IP地址正好是ARP请求分组的目的IP地址。目的物理地址和目的IP地址正好是ARP请求分组的源物理地址和源IP地址。
在windows系统的终端,输入arp -a命令可以显示ARP缓存中的所有条目。
可以看到,当源主机192.168.1.1向目的主机192.168.1.2发送ARP请求分组,并且得到对应的ARP响应分组后。
该表项192.168.1.2 8e-47-af-ef-a2-66就被添加到了ARP高速缓存中(第二项)。
可以看到,ARP高速缓存中,有的是静态映射,有的是动态映射。
通过ARP协议动态配置的表项就是动态映射。发送方检查ARP缓存,如果没找到所需物理地址,就发送ARP请求报文,并得到ARP响应报文。之后再将对应的映射添加到ARP映射表上。这种方式得到的映射表项就是动态映射。
通过手动方式添加的表项就是静态映射。这种方式添加的表项比较死板,因为对应的映射关系不一定固定不变。但是,静态映射更加安全,不会被攻击者通过ARP请求响应报文添加错误的映射关系。