计算机网络之ARP协议

引子: 众所周知, 在互联网上进行相互通信的设备必须有一个IP地址才行. 假设, 现在两个有IP地址的设备要进行通信, 用专业一点的术语来说就是要互相发送网络包, 要知道网络包是要在实实在在的物理设备上传输的(不管是网线也好还是wifi也好), 但是物理层的传输是不认识IP地址, 它只认识MAC地址, 所以两个有IP的设备要进行通信还要依赖于底层的MAC地址, 那如何根据IP地址来找到对应设备的MAC地址呢? 这个就是下面要讲的ARP协议的功能
1. 什么是ARP协议
ARP协议的全名是Address Resolution Protocol. 简单的说ARP协议的功能就是根据目标设备的IP地址找到目标设备的MAC地址. 既然是一个协议, 那肯定有其独特的结构, 来一起看一下ARP分组的组成:
计算机网络之ARP协议
文章图片
arp-packet 从上图中其实已经可以看清楚ARP协议的组成结构了, 下面还是要稍微解释下ARP协议中每一个字段的意义:
  • 硬件类型: 该字段2个字节, 用于表明ARP分组是跑在什么类型的网络上的, 例如如果是我们最常用的以太网值是1.
  • 协议类型: 该字段2个字节, 用于表明使用ARP分组的上层协议是什么类型, 例如如果是我们最常用的IPv4协议值是32.
  • 硬件地址长度: 该字段1个字节, 用于表明物理地址的长度, 因为ARP可以跑在任何物理网络上, 所以物理地址的长度不一定都是一样的, 所以这里要把物理地址的长度也用一个字段来记录. 如果是以太网则长度是6(实际上就是MAC地址的6个字节).
  • 协议地址长度: 该字段1个字节, 用于表明逻辑地址的长度, 为什么要把逻辑地址长度用一个字段的记录原因和上面的一样. 如果是IPv4协议这个值是4.
  • 类型: 该字段2个字节, 用于表明该ARP分组的类型. 现在已经有的类型只有2中: ARP请求(值是1), ARP应答(值是2).
  • 发送端硬件地址: 该字段的长度是可变的, 具体的长度依赖于硬件地址的值.
  • 发送端协议地址: 该字段的长度是可变的, 具体的长度依赖于协议地址的值.
  • 接收端硬件地址: 该字段的长度是可变的, 具体的长度依赖于硬件地址的值. 但该字段是否有值则依赖于ARP分组的类型, 如果是请求分组是没有值的, 如果是响应分组是有值的.
  • 接收端协议地址: 该字段的长度是可变的, 具体的长度依赖于协议地址的值.
2. ARP工作原理
在解释ARP工作原理之前, 先解释一个概念, 之前已经说过真正的数据包是要在物理设备上传输的, 而直接在物理设备上传输的也不是ARP分组, ARP分组还要先封装成数据链路帧然后物理层才会将数据链路帧发送出去, 下面来看一下数据链路帧的结构:
计算机网络之ARP协议
文章图片
data-link-frame ARP分组就是被封装到了数据链路帧的数据字段中了, 但是数据链路真中不仅仅能是传输ARP分组, 还能传输IP数据包等上层协议, 那数据链路帧如何知道数据字段中的数据到底是啥? 实际上就是通过类型字段来区分的, 如果是ARP分组, 则类型字段的字就是0x806.
为了方便起见, 在介绍ARP协议的工作原理的时候会按照下图来解释, 图中省略了一些不必要的字段:
计算机网络之ARP协议
文章图片
arp-process step1: 当pc1要和pc2通信的时候, 如果pc1的缓存表中有pc2的记录, 则直接将pc2的mac地址放入目的mac地址中, 直接发送相关的数据包. 如果pc1的ARP缓存表中没有pc2的记录, 就会发起一个ARP请求.
step2: pc1会将自己的IP地址和MAC地址填入ARP请求分组的源字段中, 同时将pc2的IP地址填入ARP请求分组的目的IP字段中, 并且将目的MAC地址置空(即设置成全为0). 同时将pc1的MAC地址填入到数据链路帧的源MAC字段中, 将数据链路帧的目的MAC字段置成广播地址(即全为1). 这样同一个网络中的所有主机都会收到这个ARP请求分组.
step3: 所有接收到ARP请求分组的主机都会对该ARP请求分组进行处理, 如果ARP请求分组中的IP地址和自身的不匹配则直接抛弃, 除了pc2.
step4: pc2收到了ARP请求分组, 就知道了是想要自己的MAC地址, 因此就会封装一个ARP响应分组用于响应这个ARP请求分组. pc2会将自己的IP地址和MAC地址填入到ARP响应分组的源IP和源MAC字段中, 同时将pc1的IP和MAC填入到ARP响应分组的目的IP和目的MAC字段中(pc1的信息可以在pc1发出的ARP请求分组中得知).同时将pc2的MAC地址和pc1的MAC地址填入到数据链路帧的源MAC和目的MAC字段中. 最后将ARP响应分组以单播的形式发出(因为目的MAC是知道的所以只需要用单播即可). 同时pc2还会做一件很重要的事情, 就是将pc1的MAC和IP的信息保存到pc2的ARP缓存表中, 至于为什么要这么做大家应该都可以想到.
step5: pc1收到了ARP响应分组之后就知道pc2的MAC地址了这样pc1就可以和pc2发起通信了. 同时pc1也会将pc2的MAC和IP的信心保存到pc1的ARP缓存表中.
上面说了这么多, 实际上总结一下就是一句话: ARP请求采用广播发送, ARP响应采用单播发送.
3. 揭开真实ARP分组的面纱
关于ARP协议说了这么多了, 那真是情况下ARP协议长到底长什么样呢? 毕竟看过真实的东西要比仅看看文字描述理解的更深入, 所以我就用wireshark在我本机上抓了一些包. 让我们来看看ARP协议到底长什么样:
计算机网络之ARP协议
文章图片
my-network 这是我本机的网络情况, 下面的ARP分组就是基于本机和路由器的一个交互:
这是路由器发来的ARP请求分组
计算机网络之ARP协议
文章图片
arp-request 这是本机响应给路由器的ARP响应分组
计算机网络之ARP协议
文章图片
arp-response 根据上面三张图片的内容和之前讲的应该很容易对照起来, 也可以发现实际情况下ARP的一个流程和之前说的也是一致的. 通过抓包可以对ARP分组有一个更具体的映像.
4. 总结
计算机网络的知识还是很有必要要了解一下的, 尽管可能和平时写代码的关联不大. 在学习计算机网络的时候一些资料将的还是很抽象的, 所以要更好的理解可能的话最好还是要动手抓包看看实际情况下网络中传输的到底是什么, 资料上说的数据包到底是什么.
【计算机网络之ARP协议】后序还会介绍一下在不同网段的情况下两个主机是怎么通信的, 因为二层协议是无法跨网段的, 要跨网段必须是三层协议. 因为涉及到三层协议所以就要涉及到IP地址了, 这些内容会在后序详述.

    推荐阅读