功能
根据目标IP地址,寻找网络中的目的主机,获取主机MAC地址.
实质
IP地址和MAC地址的映射,对arp缓存表项的建立,更新,查询操作.
关键数据结构
表项数组[]每一个元素(即每一个表项)都有如下重要指标:
IP地址<–>MAC地址
状态:enum etharp_state{
ETHARP_STATE_EMPTY = 0, //空
ETHARP_STATE_PENDING, //已发出ARP请求包,等待应答.
ETHARP_STATE_STABLE, //已经记录了IP<->MAC的对应关系,可以发送数据包
ETHARP_STATE_REREQUESTING_1, //表项存在但是15s后即将过期
ETHARP_STATE_REREQUESTING_2, //表项存在但是30s后即将过期
…
}
生存时间:5min
请求应答等待时间5s
对应网卡信息
表项无效项
1.表项建立时间>5min(生存时间)
2.处于PENDING状态的表项,等待ARP应答时间>5s
流程
关键点:理解发的是请求包还是数据包
ip4_output()
etharp_output()请求包处理,根据上层IP给下来的数据类型做不同处理:
广播:填写MAC地址FF_FF_FF_FF_FF_FF
多播:填写MAC地址01_00_5E_xx_xx_xx
直接调用ethernet_output()
单播:遍历表项
找到调用etharp_output_to_arp_index()进一步判断是否快过期
若快过期更改状态:ETHARP_STATE_REREQUESTING_1
无论怎样都是可以发送数据了,最终都会调用ethernet_output()进行数据发送.
找不到表项调用etharp_query()会再次发请求包等获取到目标MAC后建立表项.
待到调用ethernet_output()真正发出数据包后,
目标网卡调用ethernet_input()接收数据包
对接收到的数据包类型进行分析:
IP数据包:去掉以太网首部(pbuf_remove_header())后,递交到IP层(ip4_input())处理.
ARP数据包:去掉以太网首部(pbuf_remove_header())后,调用etharp_input()处理.
etharp_input()
1.判断包的合法性,包括检查硬件地址类型,硬件地址长度,协议类型,协议长度.
2.拷贝源IP和目标IP.
3.判断ARP包中的IP地址和目标IP地址是否一致.
4.更新ARP缓存表.
5.根据ARP包类型做处理:
请求包:
是发给自己的->调用etharp_arw()进行应答.
不是发给自己的->不应答,直接丢弃.
(两种情况:1.目标主机本身尚未配置IP.2.ARP包中的IP和目标IP不一致.)
应答包:不处理(说明已经有表项存在了)