ARP地址解析协议

2019-04-14 08:34发布

前言

    本文介绍ARP地址解析协议的主要流程及关键算法,tcp/ip协议详细信息请参考机械工业出版社出版的《TCP/IP详解》,本文部分图片摘自该书籍。

ARP协议介绍

介绍

    地址解析协议(ARP)用于实现IP地址到网络接口硬件地址的映射。     链路层通信以MAC地址标识源及目标设备,ip数据包往其他设备发送时,需要经过链路层封装,因此我们需要知道目标设备的MAC地址,通过ARP协议即可用ip获取到目标设备的地址。     (特别说明:目标设备的MAC地址并不一定就是ip地址对应的最终设备的MAC地址,而往往是下一跳的地址,因为在路由报文经过路由器时,路由器会对对报文中的MAC修改为自己的下一跳MAC地址。)

报文格式

IEEE 802.2/802.3(RFC 1042)和以太网的封装格式(RFC 894)

ARP协议实现

gratuitous ARP(免费ARP)

    网卡设备启动时发送一个gratuitous ARP请求自己的mac,检查是否在网络中存在相同的ip以及更新缓存arp路由信息,详细信息请参考http://baike.baidu.com/link?url=4XpOyapItBlRAwcS-uuR9guKo88Lx1epNNve9-KZM951vUVr6EETwFvxe-fsiRQr4xenzIRCio3RU9oS3nO_fGIe6jtqwUGLFY4nVKpVO6q

ARP实现

查看并清除arp缓存

(此处操作不是必须的) 在Windows下以管理员权限使用arp -a查看arp缓存,arp -d清除所有arp,如下图所示:

arp请求

     (报文格式请参考1.1.2 IEEE 802.2/802.3(RFC 1042)和以太网的封装格式(RFC 894))      gratuitous ARP请求主要过程为:网卡上电 -> 发送ARP请求(填充源、目标设备ip地址,填充源mac地址,目标mac为0xffffffffffff) -> 发送到物理网卡,其函数调用栈如下:     etharp_request第一个参数为当前网卡,该结构体绑定了网卡的ip相关信息及网卡收发函数,第二个参数为目标设备的ip地址,通过这两个参数的信息即可组装arp请求报文;     low_level_output第一个参数为当前网卡,第二个参数为arp报文(pbuf实现请参考《TCP/IP详解》mbuf相关章节)。
    arp报文通过网卡直接发送到直连的交换机后,因为目标mac为广播地址0xffffffffffff,交换机将该报文网所有端口进行转发,这就会出现两种情况,当前设备接收到该报文,其他设备接收到该报文:     其他设备接收到该报文时,如果ip地址有冲突(ip地址与发送设备ip地址相同),则发送arp应答报文,不相同则添加到arp缓存或者更新arp表项过期时间为0(因为arp定时器在不断统计arp表项的过期时间,当过期时,会清除该表项),arp更新及应答请参考“arp更新”、“arp应答”章节。

arp更新

    arp更新有三种情况:收到arp报文,收到ip报文,arp表项过期。
    收到arp报文时,判断该请求或者应答是否是发送给自己,如果是,则更新arp表项,如果不是发送给自己但是arp缓存中已经有对应ip的arp缓存,则同样更新arp表项;(不是发给自己的请求有两种情况,一是网卡没有配置ip,二是arp请求的目标ip不是自己的ip。)     如果是发给自己的arp请求,则需要把自己的mac地址填充到arp应答报文中,并发送到网卡;如果是应答报文(自己应答自己的报文)或者不是发给自己的报文,则不处理。
    如果收到的是ip报文,判断目标ip是否是自己的,如果是,则更新arp表项,不是,则不处理,然后将报文交给网络层处理(以太网首部有可能在链路层丢弃,也可能在网络层丢弃,不同实现代码不一定相同)。
    arp表项过期删除请参考“arp更新定时器”章节。
    更新arp表项时,如果ip已经在arp缓存表中,则更新已经存在的,如果没有空闲的表项,则将最老的表项替换(最久没有更新的表项)。

arp应答

     arp报文处理函数调用栈如下所示:      ethernetif_input主要用于接收网卡数据,并解析以太网报文首部,判断该报文是ip报文还是arp报文。     如果是arp报文则调用etharp_arp_input进行处理,该函数既处理arp请求,也处理arp应答,同时更新arp表项,处理流程请参考上一节“arp更新”。


ARP更新定时器

介绍

    在上前面章节我们已经详细介绍了在接收到ip、arp报文时怎么更新arp表过期时间及状态;要是没有收到相关报文呢,假如arp缓存表中某设备已经不在了,或者dhcp租约时间过期并且更换了ip,因此,我们需要定时更新arp表。

arp表项状态转移

    arp表项无效时的状态为empty,发送arp请求时,更新状态为pending,收到ip、arp报文时,更新对应的状态为stable,pending、stable状态下的arp表项过期时,更新为empty状态。

arp更新定时器

    arp更新定时器实现比较简单,就是一个循环定时器,不断对stable、pending状态的arp表项过期时间进行累加,超过最大值时,更新为empty状态,该过期时间也可在没有可用arp表项时用来替换最老未更新的表项。

ARP其他说明

    通常我们发送ip报文时,目标ip对应的arp表项不一定存在,此时需要先通过arp协议获取目标设备的mac地址,在发送arp请求的同时,将ip报文保存在pending状态arp表项的附加字符,当该arp表项由pending变为stable时(即获取到目标设备的mac地址),封装mac地址到arp表项附加字段并发送出去(对于tcp报文,我们就不需要等待tcp协议的超时重传了;对于无连接的udp协议,也不至于丢失udp报文)。