ARP协议浅析(2):协议分析
上一章:ARP协议浅析(1):缘起
下一章:ARP协议浅析(3):付诸实践
ARP协议原理方面的内容,来自于《手把手教你玩转ARP包》。笔者进行了一些整理,想获得更多信息参考RFC文档和《TCP-IP详解卷1:协议ARP章节,卷2:021.pdf》。
表目录
下面是ARP帧主要的格式目录
表1 物理帧头格式
表2 ARP帧格式
表3 ARP请求包中的DLC帧头
表4 ARP请求包中 ARP帧
表5 ARP响应包中 DLC Header内容
表6 ARP响应包中ARP帧的内容
为何有ARP协议?
(1) IP-MAC映射
以太网设备比如网卡都有自己全球唯一的MAC地址,它们是以MAC地址来传输以太网数据包的,它们不可能识别IP包中的IP地址,实际上网卡把受到的包提交到协议栈的缓冲,成为链路层包,再分离出IP层的包,再分离出TCP或UDP…。就像剥开竹笋,发送包则是相反的过程。
我们在以太网中进行IP通信的时候需要一个协议来建立IP地址与MAC地址的对应关系,以使IP数据包能发到一个确定的地方去。这就是ARP(Address Resolution Protocol,地址解析协议)。
讲到此处,我们可以在命令行窗口中,输入
arp -a
来看一下效果,类似于这样的条目
210.118.45.100 00-0b-5f-e6-c5-d7 dynamic
就是我们电脑里存储的关于IP地址与MAC地址的对应关系,dynamic表示是临时存储在ARP缓存中的条目,过一段时间就会超时被删除(具体时间不同操作系统不同)。
这样一来,比如我们的电脑要和一台机器比如210.118.45.1通信的时候,它会首先去检查arp缓存,查找是否有对应的arp条目,如果没有,它就会给这个以太网络发ARP请求包广播询问210.118.45.1的对应MAC地址,当然,网络中每台电脑都会收到这个请求包,但是它们发现210.118.45.1并非自己,就不会做出相应,而210.118.45.1就会给我们的电脑回复一个ARP应答包,告诉我们它的MAC地址是xx-xx-xx-xx-xx-xx,于是我们电脑的ARP缓存就会相应刷新,多了这么一条:
210.118.45.1 xx-xx-xx-xx-xx-xx dynamic
为什么要有这么一个ARP缓存呢,试想一下如果没有缓存,我们每发一个IP包都要发个广播查询地址,岂不是又浪费带宽又浪费资源?
(2) 真真假假ARP
我们的网络设备无法识别ARP包的真伪,而且也不能识别,基本的约定都是假的,会带来灾难。如果我们按照ARP的格式来发送数据包,只要信息有效计算机就会根据包中的内容做相应的反应。
这也是以太网可靠通信的基础,但是如果我能操纵网卡设备发送数据和掌握包的格式,我可以做一些欺骗和捣乱。当然,笔者只是理论分析,并不提倡读者这么做。
ARP包的格式
一个ARP包是分为两个部分的,前面一个是物理帧头或EtherHeader,后面一个才是ARP帧或Arp-Frame。
首先,物理帧头,它将存在于任何一个协议数据包的前面,我们称之为DLC Header,因为这个帧头是在数据链路层构造的,并且其主要内容为收发双方的物理地址,以便硬件设备识别。
表1 物理帧头格式
DLC Header |
|||
字段 |
长度(Byte) |
默认值 |
备注 |
接收方MAC |
6 |
|
广播时,为 ff-ff-ff-ff-ff-ff |
发送方MAC |
6 |
|
|
Ethertype |
2 |
0x0806 |
0x0806是ARP帧的类型值 |
图1是需要我们填充的物理帧头的格式,我们可以看到需要我们填充的仅仅是发送端和接收端的物理地址罢了,是不是很简单呢?
接下来我们看一下ARP帧的格式。
表2 ARP帧格式
ARP Frame |
|||
字段 |
长度(Byte) |
默认值 |
备注 |
硬件类型 |
2 |
0x1 |
以太网类型值 |
上层协议类型 |
2 |
0x0800 |
上层协议为IP协议 |
MAC地址长度 |
1 |
0x6 |
以太网MAC地址长度为6 |
IP地址长度 |
1 |
0x4 |
IP地址长度为4 |
操作码 |
2 |
|
0x1表示ARP请求包,0x2表示应答包 |
发送方MAC |
6 |
|
|
发送方IP |
4 |
|
|
接受方MAC |
6 |
|
|
接受方IP |
4 |
|
|
填充数据 |
18 |
|
因为物理帧最小长度为64字节,前面的42字节再加上4个CRC校验字节,还差18个字节 |
我们可以看到需要我们填充的同样也只是MAC,IP,再加上一个1或2的操作码而已。
ARP包的填充
(1) 请求包的填充
比如我们的电脑MAC地址为 aa-aa-aa-aa-aa-aa,IP为 192.168.0.1
我们想要查询 192.168.0.99的MAC地址,应该怎么来做呢?
首先填充DLC Header,通过前面的学习我们知道,想要知道某个计算机对应的MAC地址是要给全网发送广播的,所以接收方MAC肯定是 ffffffffffff,发送方MAC当然是自己啦,于是我们的DLC Header就填充完成了,如图,加粗的是我们要手动输入的值。
表3 ARP请求包中的DLC帧头
DLC Header |
||
字段 |
长度(Byte) |
填充值 |
接收方MAC |
6 |
Ffffffffffff |
发送方MAC |
6 |
Aaaaaaaaaaaa |
Ethertype |
2 |
0x0806 |
接下来是ARP帧,请求包的操作码当然是发送方的MAC以及IP当然填入我们自己的。然后要注意一下,这里的接收方IP填入我们要查询的那个IP地址,就是192.168.0.99了,而收方MAC填入任意值就行,不起作用。具体格式如下表。
表4 ARP请求包中 ARP帧
ARP Frame |
||
字段 |
长度(Byte) |
填充值 |
硬件类型 |
2 |
1 |
上层协议类型 |
2 |
0x0800 |
MAC地址长度 |
1 |
6 |
IP地址长度 |
1 |
4 |
操作码 |
2 |
1 |
发送方MAC |
6 |
Aaaaaaaaaaaa |
发送方IP |
4 |
192.168.0.1 |
接收方MAC |
6 |
任意值 xxxxxxxxxxxx |
接收方IP |
4 |
192.168.0.99 |
填充数据 |
18 |
0 |
如果我们构造一个这样的包发送出去,如果 192.168.0.99存在且是活动的,我们马上就会收到一个192.168.0.99发来的一个响应包,我们可以查看一下我们的ARP缓存列表,是不是多了一项类似这样的条目:
192.168.0.99 bb-bb-bb-bb-bb-bb
是不是很神奇呢?我们再来看一下ARP响应包的构造:
(2) 响应包的填充
有了前面详细的解说,你肯定就能自己说出响应包的填充方法来了吧,所以我就不细说了,列两个表就好了
比如说给 192.168.0.99(MAC为 bb-bb-bb-bb-bb-bb)发一个ARP响应包,告诉它我们的MAC地址为 aa-aa-aa-aa-aa-aa,就是如此来填充各个字段
表5 ARP响应包中 DLC Header内容
DLC Header |
||
字段 |
长度(Byte) |
填充值 |
接收方MAC |
6 |
Bbbbbbbbbbbb |
发送方MAC |
6 |
Aaaaaaaaaaaa |
Ethertype |
2 |
0x0806 |
表6 ARP响应包中ARP帧的内容
ARP Frame |
||
字段 |
长度(Byte) |
填充值 |
硬件类型 |
2 |
1 |
上层协议类型 |
2 |
0800 |
MAC地址长度 |
1 |
6 |
IP地址长度 |
1 |
4 |
操作码 |
2 |
2 |
发送方MAC |
6 |
Aaaaaaaaaaaa |
发送方IP |
4 |
192.168.0.1 |
接收方MAC |
6 |
Bbbbbbbbbbbb |
接收方IP |
4 |
192.168.0.99 |
填充数据 |
18 |
0 |
这样192.168.0.99的ARP缓存中就会多了一条关于我们192.168.0.1的地址映射。
在ARP协议相关的代码中,大部分的工具是发送请求包(Request)和接受请求包,分析后填充正确格式的响应包(Response)。这个协议就是这么工作的,下一章将分析一下具体的应用和重要的模块与函数。
上一章:ARP协议浅析(1):缘起
下一章:ARP协议浅析(3):付诸实践