正点原子lwIP学习笔记——ARP协议

1.ARP协议简介

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议

ARP协议就是根据目标IP地址以广播方式获取相应的MAC地址,并将MAC地址存入ARP缓存表。

主机 A 首先查自己的 ARP 表是否有包含主机 B 的信息,例如主机 B 的 MAC 地址,如果主机 A 的 ARP 表包含主机 B 的 MAC 地址,则主机 A 直接利用 ARP 表的主机 B 的 MAC 地址对 IP 数据包进行封装并把数据包发给主机 B ;

如果主机 A 的 ARP 表没有包含主机 B 的 MAC 地址或者没有找到主机 B 的 MAC 地址,则主机 A 就把数据包缓存起来,然后以广播的方式发送一个 ARP 包的请求报文,该 ARP 包的
内容包含主机 A 的 IP 地址、 MAC 地址、主机 B 的 IP 地址和主机 B 的全0的 MAC 地址,由
于主机 A 发送 ARP 包是使用广播形式,那么同一网段的主机都可以收到该 ARP 包,主机 B接收到这个 ARP 包会进行处理;

主机 B 接收到主机 A 的 ARP 包之后,主机 B 会对这个 ARP 解析并比较自己的 IP 地址和 ARP 包的目的 IP 地址是否相同,如果相同, 则主机 B 将 ARP 请求报文中的发送端(即主机 A )的 IP 地址和 MAC 地址存入自己的 ARP 表中。之后以单播方式发送 ARP 响应报文给主机 A ,其中包含了自己的 MAC 地址

当主机 A 收到了主机 B 的 ARP 包也是同样的处理,首先比较 ARP 包的 IP 地址是否和自己的 IP 地址相同, 如果 IP 地址相同,则把 ARP 包的信息存入自己的 ARP 表中最后对 IP数据包进行封装并把数据包发给主机 B

其中数据的格式如下图所示:
数据格式

MAC地址与IP地址作用

IP地址:用于网络寻址,它作用空间是广域网可变,解决数据在外网传输。
MAC地址:用于链路层寻址,它作用空间是局域网不可变,不重复。

同一网段发数据
不同网段发数据
同一网段就可以由MAC地址直接发;不同网段就要借由IP地址进行转发,然后进入同一局域网内,就可以再由MAC地址进行发送。

2.ARP协议原理

发送ARP请求包

发送请求包流程
首先判断是广播还是单播,广播就是接通过low_level_output发送;单播,就要查询MAC地址,找到了就发送数据包;没找到,就要挂起数据,构建ARP请求包广播出去。

翻阅源码etharp_output,首先会查询是广播多播还是单播,广播就直接广播出去;多播就要根据多段地址来进行数组的输入,然后传出去;否则就是单播,先判断是否与主机处于同一网段,如果不是,就要修改IP地址为网关地址,来让网关转发;

定义了结构体stharp_entry如下所示:

/** ARP states */
enum etharp_state {
  ETHARP_STATE_EMPTY = 0,
  ETHARP_STATE_PENDING,
  ETHARP_STATE_STABLE,
  ETHARP_STATE_STABLE_REREQUESTING_1,
  ETHARP_STATE_STABLE_REREQUESTING_2
#if ETHARP_SUPPORT_STATIC_ENTRIES
  , ETHARP_STATE_STATIC
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
};

struct etharp_entry {
#if ARP_QUEUEING
  /** Pointer to queue of pending outgoing packets on this ARP entry. */
  struct etharp_q_entry *q;
#else /* ARP_QUEUEING */
  /** Pointer to a single pending outgoing packet on this ARP entry. */
  struct pbuf *q;
#endif /* ARP_QUEUEING */
  ip4_addr_t ipaddr;
  struct netif *netif;
  struct eth_addr ethaddr;
  u16_t ctime;
  u8_t state;
};

static struct etharp_entry arp_table[ARP_TABLE_SIZE];

其中包含了pbuf的结构体q,用来挂起数据包,IP地址ipaddr,网卡的结构体netif,指向当前网卡MAC地址eth_addr结构体ethaddr,生存时间ctime(每个ARP缓存表中的元素的存在时间,超过这个时间就会被清除),状态state变量表明ARP处于什么状态;

ARP的状态变量通过enum来枚举:ETHARP_STATE_EMPTY,这个状态表示ARP缓存表处于初始化的状态,所有表项初始化之后才可以被使用;ETHARP_STATE_PENDING表示该表项处于不稳定状态,此时该表项只记录到了IP 地址,但是还未记录到对应的 MAC 地址。(lwIP 内核已经发出一个关于该 IP 地址的 ARP 请求到数据链路上且lwIP内核还未收到 ARP 应答,此时ETHARP_STATE_PENDING 状态下会设定超时时间( 5 秒), 当计数超时后, 对应的表项将被删除超时时间需要宏定义ARP_MAXPENDING 来指定,默认为5 秒,如果在5 秒之前收到应答数据包,那么系统会更新缓存表的信息,记录目标 IP 地址与目标 MAC 地址的映射关系并且开始记录表项的生存时间,同时该表项的状态会变成ETHARP_STATE_STABLE 状态。);ETHARP_STATE_STABLE,当收到应答之前,这些数据包会暂时挂载到表项的数据包缓冲队列上,收到应答之后,系统已经更新ARP 缓存表,那么系统发送数据就会进入该状态;ETHARP_STATE_STABLE_REREQUESTING_1和ETHARP_STATE_STABLE_REREQUESTING_2都是过渡状态。

如果判断情况为广播或者多播直接调用ethernet_output进行发送;该函数会通过payload指针进行移位操作,把类型、广播的MAC地址等信息加入pbuf的头部

如果判断情况为单播,也就是说需要用到ARP这边的通讯协议,就会遍历ARP缓存表;如果找到了缓存表中有相对应的发送IP地址,那么就直接调用etharp_output_to_arp_index函数把数据包发送出去

如果没有找到,调用etharp_query发送ARP请求包;首先会判断是不是单播,然后判断是否存在ARP缓存表,没有表项就用etharp_request创建一个缓存表,发送一个ARP请求包;这个函数中调用etharp_request_dst,进入etharp_request_dst后调用etharp_raw;etharp_raw创建了一个pbuf,然后pbuf_alloc申请对应的内存,然后添加ARP的首部,hdr = (struct etharp_hdr *)p->payload;然后在etharp_hdr结构体中填写相应的头部信息,在hdr中填写相应的ARP的MAC地址;再填写IP地址以及其余头部信息;最后调用ethernet_output进行发送(处理完ARP请求包,再加上以太网的头部信息然后发送出去)。

接收ARP应答包

接收ARP流程示意图
在带操作系统的FreeRTOS版本中,通过tcpip_thread中进行操作,在这里面会有调用tcpip_input函数,里面调用ethernet_input函数;这个函数会判断是IP还是ARP数据包,IP就会调用ip4_input,而ARP就会调用etharp_input进行处理;

etharp_input函数中,会通过etharp_hdr的定义结构体hdr,来读取当前pbuf的payload指针;如果这时是更新ARP缓存表,就会进入etharp_update_arp_entry;如果是ARP请求包,就会进入etharp_raw发送ARP应答包;

如果是更新缓存表,进入etharp_update_arp_entry更新;更新完成后调用ethernet_output进行发送,也是在其中通过payload指针添加以太网首部,添加以太网类型,以及目标和主机的MAC地址;

如果是ARP请求包,就会进入etharp_raw构建应答包;首先pbuf_alloc申请pbuf内存,然后通过hdr操作payload添加ARP头部信息,完成构建,调用ethernet_output添加以太网首部并发送。

2.ARP协议原理

ARP协议原理示意图
这张图就是对以上源码解读的总结性框图,可以根据这张图了解ARP的总体操作流程

3.ARP协议报文结构

ARP报文结构
头部也就是以太网头部信息,就是MAC的目标和主机地址,还有帧类型,在input中就是通过帧类型来判断是IP还是ARP:0x0806是ARP,0x0800是IP;然后就是数据,其中通过op来判断是请求还是应答包,1代表请求,2代表应答

总结

这一章讲述了在转发过程中,如何通过ARP协议来获得MAC地址,非常重要,通过ARP的请求包和应答包完成MAC地址的传输,进入后续的网络协议的数据传输操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值