谈ARP

作者: 404Not_Found | 来源:发表于2021-10-25 14:05 被阅读0次
  • 作者: 雪山肥鱼
  • 时间:20211024 16:18
  • 目的: ARP 回顾
# 为何需要ARP
# 地址映射
  ## 静态映射
  ## 动态映射
# ARP协议
  ## dpdk中解ARP
  ## ARP的分组与封装
  ## ARP的操作
  ## 代理ARP
# ARP的实现
  ## 高速缓存表
  ## 队列
  ## 输出模块
  ## 输入模块
  ## 高速缓存控制模块
  ## 举例

最近学习dpdk的一些代码,example的例子大多是arp与icmp 相关。于是又掏出<<TCP/IP协议族>>复习下。以前没有整理的习惯。今天整理一下。

文中讨论的物理地址,均用以太网的MAC地址

为何需要ARP

网络层的IP协议,能够把分组从源主机,交付到目的主机,首先要知道 如何交给下一跳的。IP分组可以通过咨询路由表找出下一跳的地址。
找到了又怎么处理呢?
IP包,总归要经过数据链路层的,那么不仅要知道下一条的ip地址,同样也需要知道mac地址。

如果获得同一网络下其他节点的mac地址?这就需要ARP协议。

地址映射

在IP层,逻辑地址即IP地址。ipv4 32位,ipv6 128位
但是IP层的包需要通过物理层才能达到主机和路由器。在这一层,通过物理地址来识别。物理地址是一个本地地址,它的管辖范围是 本地网络

  • 物理地址在本地范围内必须唯一
    但全局上没有此要求。
  • 物理地址(并非总是)在硬件上实现。
    以太网mac 地址 只是物理地址的一个子集。是物理地址的一种,写在了主机or录音透气的网络接口卡(NIC)中。

物理地址和IP 是两种不同的标识,但是我们都需要。一个物理地址可以为不同的网络层提供服务(IP/IPX),也就是网络层不仅有IP协议,也有IPX等其他协议。
网络包(如IP协议组的)也可以通过不同的物理网,如以太网(MAC地址)和localtalk(Apple) 发出去。

逻辑地址+物理地址 是一对组合。互相映射。

静态映射

人工维护一张表

  • 缺陷
  1. 一台机器有可能更换INC,就更新了 物理地址
  2. 某些局域网,如LocalTalk,每次其对应的物理地址都会改变
  3. 移动电脑可以从一个物理网,转移到另一个物理网络。会引起物理地址改变.(以太网 转移到 LocalTalkc 网)

以上动作都会导致静态表更新。增加网络性能开销。

动态映射

相对于静态映射,只有更换,就会刷新。

ARP 协议

ARP在TCP/IP协议族中的位置.png arp流程.png

实际上还是属于网络层,但是偏下,可以算得上是 物理层和IP层的枢纽。

何时发送ARP:

  • 主机需要知道另一台主机or 路由器的 mac地址(也就是说它现在不知道),故而群发。
  • 收到者解包,发现不是自己的IP 则丢到,是则带上自己的mac地址 回复即可。

dpdk 中 解 ARP

所以在dpdk 解包的过程中,解udp, 解icmp 解icmp是不同的。

1. udp:
a) ether_hdr
b) ether_type_ipv4
c) ether_hdr ---> iphdr
d) iphdr->next_protoal_id == IPPOTO_UDP

2. icmp:
a) ether_hdr
b) ether_type_ipv4
c) ether_hdr ---> iphdr
d) iphdr ->icmphdr
e) icmphdr->icmp_type == IP_ICMP_ECHO_REQUEST

3. arp:
a) ether_hdr
b) ether_type_arp
c) ether_hdr-> arp_hdr

上述流程注意:arp 这一个解包,并没有优先匹配ipv4, 因为arp只存在于ipv4, ipv6 用RA/RS NA/NS 代替了 ARP 功能.

ARP的分组与封装

ARP 分组.png

ARP分组里面不仅有 mac和IP,还有其他的字段。

  • 硬件类型:
    定义ARP网络类型(物理/数据链路)。以太网类型是1
    ARP可用在任何物理网络中
  • 协议类型,ipv4 : 0800h
  • 硬件长度
    物理地址长度,以太网的MAC是6
  • 协议长度
    逻辑地址长度,ipv4 就是4
  • 操作
    ARP请求,ARP回答

封装:


ARP分组封装.png

ARP 的操作

  1. 发送方知道对方IP,但不知道MAC
  2. IP请求ARP,创建一个ARP请求报文,填入发送方物理地址,发送方IP,及目标IP地址,MAC地址全部填0
  3. 交给数据链路层,封装成帧,广播
  4. 各个主机判断
  5. 符合目标IP的,用ARP报文进行回答。回答中包含了物理地址。单播方式转发
  6. 接受报文,知道目标物理地址了。存到ARP表中
  7. 发送IP报文,单播形式发出。
ARP 操作流程.png

注意点:

  1. IP与16进制整数的转换
    130.23.42.20 =》 0x82172B14 =》20 205 625 424 200多亿
  2. ARP 包含2次MAC地址
    以太网帧头,与ARP分组中

四种情况

  1. 发送方是主机,发送给同一网络上的另一台主机。
    单纯的主机IP


    图片.png
  2. 发送方主机,发送给另一个网络上的主机。
    主机查路由表,找到终点的下一跳,路由器的ip地址。如果没有,就找默认网关。则寻找 路由器的 ip+mac 的组合


    图片.png
  3. 发送方是路由器,发给另一个网络主机的数据报文。
    同上,只不过是路由器vs路由器之间的。


    图片.png
  4. 路由器发给同一网络上的主机,同情况1


    图片.png

代理ARP

起到子网划分的作用
定义:proxy ARP 代表了一组主机的ARP。当运行代理ARP的路由收到一个ARP请求,希望找到主机中的某一台mac地址时,路由器就返回自己的硬件mac地址。(有点ARP欺骗的意思)

举例.png
  1. 增加了一个运行代理ARP的路由器。这种情况下,路由器代表了所有安装子网上的主机。
  2. 收到一个目标地址 图中3者之一的arp请求。
  3. 代理arp回答自己的mac地址。当然 代理arp路由器与各个主机之间也有各自的arp表。

ARP的实现

架构:


ARP架构.png
  1. 高速缓存表
  2. 队列
  3. 输出模块:将未得到mac地址的ip包发送到队列中
  4. 输入模块:从队列中取出分组,并连同解析出的物理地址封装发送到数据层
  5. 告诉缓存控制模块

高速缓存表

cache 作用。
包含字段


字段.png
  • 状态:
    free: 生存周期已到,可以清空
    pending:请求已经发出,但未收到
    resolved:完成映射
  • 接口号:一个路由器or网络主机能够连接到多个不同的网络,每个连接都有不同的接口好。每个网络还可能有不同的硬件类型和协议类型
  • 队列号:ARP使用带编号的队列把等待地址解析的分组进行排队。发往同一个终点的分组通常放在同一个队列中。
  • 尝试: 发了多少次arp
  • 超时: 生存时间

队列

一组队列,每个队列对应一个终点,用来ARP尝试解析硬件地址时暂存IP分组的地方。
输出模块把未解析的分组发送到相应(以目的分组)队列。
输入模块从队列中取出分组,打包,发送给数据层传输。

输出模块

ARP_Output_Module( ) 
{
  睡眠,直至收到来自IP软件的IP分组
  检查告诉缓存表,寻找这个IP分组终点对应的表项。
  if(找到)
  {
      if(状态是RESOLVED)
      {
          从该表项中提取出硬件地址的值
          把分组联通硬件地址一起发送到数据链路层
          返回
      }//end if
      if(状态是Pending) //既然是pending,说明就已经准备好了一个队列
      {
          把IP分组放入相应的队列(目标IP)
          返回
      }
  }//end if
  if(未找到)
  {
      创建一个高速缓存表项,状态设置为Pending;Attempts设置为1
      创建一个队列(目标IP)
      把分组放入队列中
      发送一个ARP请求
      返回
  }//endif
}//end module

输出模块主要负责

  1. 没有表项,队列里hold住IP分组,发送ARP请求,
  2. 拿到MAC或者 表项中存在,就带着MAC 发包

输入模块

ARP_Input_Module()
{
  睡眠,直到一个ARP分组(请求or回答)到达
  检查高速缓存表,寻找相应的表项
  if(找到)
  {
    更新表项 //Pending -> Resolved, 同时增加超时时间
    if(状态是Pending)//下次进来就不是Pending,是Resolved了
    {
      while(相应的队列非空)
      {
        从队列中取出一个分组
        将该分组连同硬件地址一起发送
      }//endif
    }//endif
  }//endif
  if(未找到)
  {
    创建一个表项
    新建表象加入表中
  }//endif
  if(分组是请求分组)
  {
    发送ARP回答
  }//endif
  返回
}//end module

输入模块主要负责:

  1. 收到ARP请求发送回复
  2. 收到回复,表中有就带着mac发数据,表中没有就,创建表项

高速缓存控制模块

 ARP_Cache_Control_Module()
{
  睡眠,直至计时器到时
  Repeat for 高速缓存表中的每一项
  {
    if(状态为free)
    {
        继续
    }//endif
    if(状态是Pending)
    {
       Attemp value +1
       if(尝试次数大于最大数)
       {
          把状态改为free
          撤销相应队列
       }//endif
       else
       {
          发送一个ARP请求
       }// endif
       继续
    }//endif
    if(状态为Resloved)
    {
        递减超时字段的值
        if(超时字段的值小于or = 0)
        {
            状态置为free
            撤销相应队列
        }//endif
    }//endif
  }//end repeat
  返回
}//end module

举例

图片.png
  1. 输出模块收到一个IP数据报。并且状态是R。直接带着MAC地址发送
  2. 输出模块收到一个IP数据包,表项中无目的IP与mac映射关系。增加一个表项,状态值为Pending,且尝试次数+1,同时输出模块根据这个终点增加一个队列,暂存IP包。 最后发出ARP请求。
    图片.png
  3. 输入模块收到一个ARP分组,将状态从P改为R,重置超时时间,发送队列数据包。


    图片.png
    图片.png
  4. 刷新表项,递减超时时间


    图片.png
    图片.png

相关文章

网友评论

      本文标题:谈ARP

      本文链接:https://www.haomeiwen.com/subject/xkzkaltx.html