对于ARP协议, 我本来是不了解的,只是解决了两个ARP相关的P2的Bug后,也就懂了。本文将从原理的角度对ARP做一个透析。

1. 什么是ARP?

ARP(Address Resolution Protocol),也就是地址解析协议。解析什么地址?将IP地址解析为以太网MAC地址(i.e. 物理地址)的协议。在以太网当中 , 网络设备是通过物理地址表示的 , 这个物理地址就是48位的以太网地址。 简言之,ARP 协议是用来将 32 位的IP地址解析为48 位的以太网地址的协议。

2. 为什么需要ARP协议?

在局域网中,当主机或其他网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(也就是IP地址)。但是,仅仅知道IP地址是不够的,因为IP数据报文必须封装成帧(frame)才能通过物理网络发送,因此发送站还必须有接收站的物理地址,所以需要一个从IP地址到物理地址的映射。于是,ARP协议应运而生。

3. ARP报文格式

ARP是一个独立的三层协议,所以ARP报文在向数据链路层传输时不需要经过IP协议的封装,而是直接生成自己的报文,其中包括ARP报头,到数据链路层后再由对应的数据链路层协议(如以太网协议)进行封装。 ARP报文分为ARP请求和ARP应答报文两种,其报文格式定义如下:

一个典型的ARP请求包看起来是这个样儿滴,

在Linux源代码中,ARP报头是这么定义的,

/* http://src.illumos.org/source/xref/linux-master/include/uapi/linux/if_arp.h#139 */
/*
140 * This structure defines an ethernet arp header.
141 */ struct arphdr {
__be16 ar_hrd; /* format of hardware address */
__be16 ar_pro; /* format of protocol address */
unsigned char ar_hln; /* length of hardware address */
unsigned char ar_pln; /* length of protocol address */
__be16 ar_op; /* ARP opcode (command) */ #if 0
/*
152 * Ethernet looks like this : This bit is variable sized however...
153 */
unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
unsigned char ar_sip[]; /* sender IP address */
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
unsigned char ar_tip[]; /* target IP address */
#endif };

下面对arp header的各个字段做一个说明:

  • Hardware type (硬件类型): 占2个字节,表示ARP报文可以在哪种类型的网络上传输,当值为1时表示为以太网。
  • Protocol type (上层协议类型): 占2个字节,表示硬件地址要映射的上层协议地址类型, 当上层协议为IP时其值为0x0800。
  • Hardware address length(硬件地址长度): 占1个字节,标识MAC地址长度,以字节为单位,此处为6。
  • Protocol address length(上层协议地址长度): 占1个字节,标识IP地址长度时,以字节为单位,此处为4。
  • Operation code(操作类型): 占2个字节,指定本次ARP报文的类型。1-ARP请求,2-ARP应答。
  • Sender hardware address(发送方硬件地址): 占6个字节,表示发送方设备的硬件地址。
  • Sender protocol address(发送方上层协议地址): 占4个字节,表示发送方设备的上层协议地址,对以太网来说就是发送方设备的IP地址。
  • Target hardware address(接收方硬件地址): 占6个字节,表示接收方设备的硬件地址。注意: 在请求报文中该字段值全为0, 即00-00-00-00-00-00,表示任意地址,因为现在还不知道目标的MAC地址。
  • Target protocol address(接收方上层协议地址): 占4个字节,表示接收方设备的上层协议地址,对以太网来说就是接收方设备的IP地址。

ARP报文并不是直接在网络层发送的,它还是需要向下传输到数据链路层,所以当ARP报文传输到数据链路层后,需要再次进行封装。以以太网为例,ARP报文传输到以太网数据链路层后会形成ARP帧。一个典型的以太网帧看起来是这样子滴,

以太网帧头中包含了三个字段,说明如下:

  • Destination address(目标MAC地址): 占6个字节,如果是ARP请求帧,因为它是一个广播帧,所以要填上广播MAC地址 -- FF-FF-FF-FF-FF-FF,其目标是网络上的所有主机。
  • Source address (源MAC地址): 占6个字节,发送ARP帧的节点的MAC地址。
  • Type (类型): 占2个字节,用来标识帧封装的上层协议,因为本帧的数据部分是ARP报文,所以直接用ARP的协议号0x0806表示即可。

4. ARP地址解析原理

无论是主机还是交换机,都有一个用来缓存同一网络设备IP地址和MAC地址的ARP映射表,用于数据帧的转发。设备通过ARP解析到目标MAC地址后,将会在自己的ARP映射表中增加IP地址到MAC地址的映射表项,以用于后续到同一目的地数据帧的转发。 ARP表项分为动态ARP表项和静态ARP表项,这里不做详细介绍,只简单介绍一下动态ARP表项。 动态ARP表项由ARP协议通过ARP报文自动生成和维护,可以被老化,可以被新的ARP报文更新,也可以被静态ARP表项所覆盖。当到达老化时间或接口关闭时会删除相应的动态ARP表项。

为了讲述ARP地址解析原理,先上个图,该图来源于Book 《COMPUTER NETWORKS》(FIFTH EDITION) Page 468。

4.1 同一网段中两个主机的ARP地址解析 (Host 1 <---> Host 2)

Host # IP MAC
Host 1 IP1: 192.32.65.7 E1: B8:AE:ED:BF:EE:B6
Host 2 IP2: 192.32.65.5 E2: C0:7C:D1:3D:17:19
  • - Host 1 首先查看它自己的ARP表(一个IP地址与MAC地址的映射表),确定其中是否包含Host 2的IP地址和对应的MAC地址。如果找到了对应的MAC地址E2, 则Host 1直接利用ARP表中找到的MAC地址E2对IP数据包进行帧封装,并将数据包发送给Host 2;
  • 102 - 如果Host 1在ARP表中找不到对应的MAC地址E2, 则先缓存该数据报文,按后以广播方式(目标MAC地址为广播MAC地址 - FF:FF:FF:FF:FF:FF, 在同一个网段里的任何节点都能收到)发送一个ARP请求报文。 在这个ARP请求报文中,发送端(源)IP地址为IP1(192.32.65.7), 发送端(源)MAC地址为E1(B8:AE:ED:BF:EE:B6), 目的IP地址为IP2(192.32.65.5), 目的MAC地址为00:00:00:00:00:00(因为还不知道目的MAC地址是啥)。 因为ARP请求报文是以广播的方式发送,所以该网段上的所有主机都可以接收到该请求包,但只有其IP地址与目的IP地址一致的Host 2才会对该请求进行处理。那些IP地址与目的IP地址不一致的Host会把该ARP请求包直接drop掉;
  • - Host 2将ARP请求报文中的发送端(即Host 1)的IP地址(192.32.65.7)和MAC地址(B8:AE:ED:BF:EE:B6)存入自己的ARP表中,然后以单播的方式向Host 1发送一个ARP响应报文,该响应报文中就包含了它的MAC地址E2(C0:7C:D1:3D:17:19), 也就是原来在请求报文要请求的目的MAC地址;
  • - Host 1在收到来自Host 2的ARP响应报文后,将Host 2的MAC地址E2(C0:7C:D1:3D:17:19)加入到自己的ARP表中以用于后续报文的转发,同时将原来缓存的IP数据包再次修改(在"目的MAC地址"字段填上Host 2的MAC地址E2(C0:7C:D1:3D:17:19))后发送出去。

P.S. 下面给出一张来自Mellanox的培训材料截图,以帮助更好地理解以太网的ARP原理

4.2 不同网段的两个主机的ARP地址解析

Node # IP MAC
Host 1 IP1: 192.32.65.7 E1: B8:AE:ED:BF:EE:B6
Gateway

193.32.65.1/192.168.63.1

E3/E4:

Host 4 IP4: 192.32.63.8 E6: 6C:92:BF:1B:54:07
  • - 如果Host 1不知道网关的MAC地址(也就是在Host 1的ARP表中没有网关对应的MAC地址表项),则Host 1现在本网段(192.32.65.0/24)中发出一个ARP请求广播包,ARP请求报文中的目的IP地址为网关的IP地址(192.168.65.1),代表其目的就是想获得网关的MAC地址。如果Host 1已经知道网关的地址,则略过此步;
  • 202 - 网关收到ARP广播包后同样会给Host 1发送一个ARP应答包。当Host 1从收到的ARP报文中获得网关的MAC地址后,在Host 1向Host 4发送的原报文的目的MAC地址字段填上网关的MAC地址后发给网关;
  • - 如果网关的ARP表中已经有Host 4对应的MAC地址,则网关直接将来自Host 1的报文中的目的MAC地址字段替换为Host 4的MAC地址后转发给Host 4; 
  • - 如果网关的ARP表中还没有Host 4对应的MAC地址,则网关会再次向Host 4所在的网段发送ARP广播请求,此时目的IP地址为Host 4的IP地址。当网关收到来自Host 4的应答报文后,从中获取到Host 4的MAC地址,就把由Host 1发来的报文重新在目的MAC地址字段替换为Host 4的MAC地址后发送给Host 4。

5. ARP诊断工具

  • arp(8) - manipulate the system ARP cache
  • arping(8) - send ARP REQUEST to a neighbour host

e.g.

$ arp -a
localhost (192.168.1.1) at 0c::2c:c0::c8 [ether] on eth0 $ ping 192.168.1.103
PING 192.168.1.103 (192.168.1.103) () bytes of data.
bytes from 192.168.1.103: icmp_seq= ttl= time= ms
bytes from 192.168.1.103: icmp_seq= ttl= time= ms
bytes from 192.168.1.103: icmp_seq= ttl= time= ms
bytes from 192.168.1.103: icmp_seq= ttl= time=2.84 ms
^C
--- 192.168.1.103 ping statistics ---
packets transmitted, received, % packet loss, time 4015ms
rtt min/avg/max/mdev = 2.842/1069.057/2431.390/941.354 ms, pipe $ arp -a
localhost (192.168.1.103) at 1c::f6::cc:fc [ether] on eth0
localhost (192.168.1.1) at 0c::2c:c0::c8 [ether] on eth0 $ arping -I eth0 -s 192.168.1.102 192.168.1.103
ARPING 192.168.1.103 from 192.168.1.102 eth0
Unicast reply from 192.168.1.103 [1C::F6::CC:FC] .293ms
Unicast reply from 192.168.1.103 [1C::F6::CC:FC] .082ms
Unicast reply from 192.168.1.103 [1C::F6::CC:FC] .626ms
^CSent probes ( broadcast(s))
Received response(s)

参考资料:

  • https://en.wikipedia.org/wiki/Address_Resolution_Protocol
  • http://www.eventhelix.com/RealtimeMantra/Networking/Arp.pdf
  • http://www.cs.virginia.edu/~cs458/slides/module06-arpV2.pdf
  • https://tools.ietf.org/html/rfc826

透析ARP原理的更多相关文章

  1. java--序列化及其算法透析

    有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...

  2. Ruby设计模式透析之 —— 适配器(Adapter)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400153 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  3. Ruby设计模式透析之 —— 组合(Composite)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  4. OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)

    OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...

  5. lambda匿名函数透析

    lambda匿名函数透析 目录 1       匿名函数的作用... 1 2       匿名函数的格式... 1 3       匿名函数实例代码... 3   1         匿名函数的作用 ...

  6. 图解ARP协议(四)代理ARP原理与实践(“善意的欺骗”)

    一.代理ARP概述 我:当电脑要访问互联网上的服务器,目标MAC是什么? 很多小伙伴在刚学习网络协议的时候,经常这样直接回应:不就是服务器的MAC嘛! 这时我会反问:那电脑怎么拿到这个服务器的MAC地 ...

  7. 简析ThreadLocal原理及应用

    简析ThreadLocal原理及应用 原创: 东晨雨 JAVA万维猿圈 4月17日 ThreadLocal的源码加上注释不超过八百行,源码结构清晰,代码也比较简洁.ThreadLocal可以说是Jav ...

  8. Excel数据分析 --数据透析表

    数据透析表主要用于各种数据总汇,对各项数据指标进行分类统计 实例分析 如下所示:是一份销售流水数据,有时间,地区,销售员,商品名称,数量,单价和金额几个字段,如下所示: 现在针对不同的数据汇总需求,可 ...

  9. [转]CAP原理与最终一致性 强一致性 透析

    在足球比赛里,一个球员在一场比赛中进三个球,称之为帽子戏法(Hat-trick).在分布式数据系统中,也有一个帽子原理(CAP Theorem),不过此帽子非彼帽子.CAP原理中,有三个要素: 一致性 ...

随机推荐

  1. Jquery 自定义插件写法(示例)

    (function ($) { $.SmsHelper = $.SmsHelper || {}; $.extend($.SmsHelper, { //插件具体实现代码 yzmnum: 60, Ajax ...

  2. .NET 匿名方法的BUG,请专家解答

    匿名方法是.NET 3.5之后的一个好东东,很多人使用,但是我在最近的工作当中发现了一个问题. 请专家解答 //list里存放10个数字 List<); ; i < ; i++) { li ...

  3. svn自动更新服务器最新代码

    1.很简单打开dos界面 cd到svn exe目录下,运行 cd C:\Program Files\TortoiseSVN\bin    --svn安装目录(作者使用时TortoiseSVN客户端,其 ...

  4. 比较git commit 两个版本之间次数

    #!/bin/bash f1="$1*" f2="$2*" echo "第一个版本:"$f1 echo "第二个版本:" ...

  5. C# 中 String 类型的详细讲解

    C# 字符串(String) 在 C# 中,您可以使用字符数组来表示字符串,但更常见的做法是使用 string 关键字来声明一个字符串变量.string 关键字是 System.String 类的别名 ...

  6. .Net Core 2.0 的 ConsoleApp 搭建 Quartz(xml配置)windows服务

    零.创建一个.Net Core 2.0 的ConsoleApp 应用,建完就是这个样子了. 添加Log4Net 的引用,(不想看可以不看,个人习惯)Install-Package log4net添加C ...

  7. 初学python之路-day15

    一.生成器send方法 # send的工作原理 # 1.send发送信息给当前停止的yield # 2.再去调用__next__()方法,生成器接着往下指向,返回下一个yield值并停止 # 案例: ...

  8. B - 영어(字符串)

    原题链接 B - 영어 Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit S ...

  9. break与continue语句

    1.break:立即退出循环 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  10. 洛谷P3676 小清新数据结构题(动态点分治+树链剖分)

    传送门 感觉这题做下来心态有点崩……$RMQ$求$LCA$没有树剖快我可以理解为是常数太大……然而我明明用了自以为不会退化的点分然而为什么比会退化的点分跑得反而更慢啊啊啊啊~~~ 先膜一波zsy大佬 ...