故事作者:冯学卫

最近创作

看看TA的故事

网络协议详解01—ARP协议

已锁定

冯学卫

官方工程师

  • 帖子

    180
  • 精华

    42
  • 被关注

    220

论坛等级:侠圣

注册时间:2007-08-03

钻石 钻石 如何晋级?

网络协议详解01—ARP协议

724

14

2023-11-03 16:04:43

star star star star star

ARP 简介

ARP协议是“Address Resolution Protocol”(地址解析协议)的缩写。在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。在以太网中,一个主机要和另一个主机进行直接通信,必须要知道目标主机的MAC地址。但这个目标MAC地址是如何获得的呢?它就是通过地址解析协议获得的。所谓“地址解析”就是主机在发送数据帧前将目标IP地址转换成目标MAC地址的过程。ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。

正常情况下,每台主机都会在自己的ARP缓冲区中建立一个 ARP列表,以表示IP地址和MAC地址的对应关系。源主机需要将一个数据包要发送到目的主机时,首先检查自己 ARP列表中是否存在该 IP地址对应的MAC地址,如果有﹐就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中。

① 要发送网络包给172.20.1.2,但不知MAC地址?

② 在局域网发出广播包“172.20.1.2的MAC地址是什么?”

③ 其他主机不会回应,只有172.20.1.2主机进行回应

④ 回应的包“172.120.1.2的MAC地址是08:00:20:74:CE:EC”

根据上图我们看到,主机A发送的请求广播包同时被其他主机收到,然后除主机B之外的其他主机收到之后(发现不是问自己)则丢弃。而主机B收到之后,根据请求包里面的信息(有自己的IP地址),判断是给自己的,所以不会做丢弃动作,而是返回ARP回应包。

 ARP请求是通过广播方式来实现的,那么,PC2返回ARP回应包,是否也需要通过广播来实现呢?答案是否定的。大部分网络协议在设计的时候,都需要保持极度克制,不需要的交互就砍掉,能合并的信息就合并,能不用广播就用单播,以此让带宽变得更多让网络变得更快。

 那么,ARP回应包是如何处理的?这里需要特别关注ARP请求包的内容,在上面的图解里面,ARP请求包的完整信息是:我的IP地址是IP1,MAC地址是MAC1,请问谁是PC2,你的IP2对应的MAC地址是多少?

为了让大家更好的理解ARP协议以及广播和单播的概念,我们来看一下用Wireshark抓取到的真实网络中的ARP过程,通过数据包的方式来呈现,地址信息如下,部分MAC信息隐去。


ARP请求包

ARP回应包

ARP协议的报文帧结构

> Hardware type :  硬件类型,标识链路层协议

> Protocol type: 协议类型,标识网络层协议

> Hardware size :硬件地址大小,标识MAC地址长度,这里是6个字节(48bti)

> Protocol size: 协议地址大小,标识IP地址长度,这里是4个字节(32bit)

> Opcode: 操作代码,标识ARP数据包类型,1表示请求,2表示回应

> Sender MAC address :发送者MAC

> Sender IP address :发送者IP

> Target MAC address :目标MAC,此处全0表示在请求

> Target IP address: 目标IP

在次通过Wireshark 的抓包验证ARP协议的报文帧结构

ARP请求包

ARP回应包

ARP高速缓存

如果每发送一个IP数据报都要进行一次ARP请求,以此确定MAC地址,那将会造成不必要的网络流量,因此,通常的做法是把获取到的MAC地址缓存一段时间。即把第一次通过ARP获取到的MAC地址作为IP对MAC的映射关系记忆到一个ARP缓存表中,下一次再向这个IP地址发送数据报时不需要重新发送ARP请求,而是直接使用这个缓存表当中的MAC地址进行数据报的发送。这样,再一定程度上也防止了ARP包在网络上被大量广播的可能性。

Python 实现ARP协议

Python先安装Scapy模块,然后利用Scapy提供函数功能来实现ARP请求报文帧的铸造。

Scapy 铸造ARP数据包的方法:

arp_request=Ether(dst='FF:FF:FF:FF:FF:FF')/ARP(op=1,hwdst='00:00:00:00:00:00',pdst='192.168.219.180’)

arp_request.show()可以查看铸造的包的信息:

铸造好的ARP 请求包可以通过srp()函数发送。srp()可以发送一个以太二层的数据包并等待回复,这里的回复是一个复杂的数据结构。

这里srp()函数的返回值是一个特殊的类,分为收到结果的包,和未收到结果的包。这里可以看到, srp()将返回值做成了一个元组。arp[0]就是收到的数据包,在收到的数据包中,又是列表,列表中的每一元素都是有发送的数据包和接收到的数据包组成,arp[0].res可以产生这个列表作为一个清单。清单的第一个元素(就是第一个响应的数据包)的第二个位置就是保存的接收到的数据包。在此位置查看此包的hwsrc字段,就是问题的答案,就是目标的mac地址。

Python3 源代码实现ARP的请求发送

代码执行结果

Python3 源代码实现本地局域网的地址扫描

代码执行结果

通过Python代码实现ARP协议可以使我们对ARP协议有更深入的了解。

网络协议详解01—ARP协议 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

冯工聊工业网络

共有36条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。