透析ARP原理
对于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原理的更多相关文章
- java--序列化及其算法透析
有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...
- Ruby设计模式透析之 —— 适配器(Adapter)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400153 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...
- Ruby设计模式透析之 —— 组合(Composite)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...
- OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)
OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...
- lambda匿名函数透析
lambda匿名函数透析 目录 1 匿名函数的作用... 1 2 匿名函数的格式... 1 3 匿名函数实例代码... 3 1 匿名函数的作用 ...
- 图解ARP协议(四)代理ARP原理与实践(“善意的欺骗”)
一.代理ARP概述 我:当电脑要访问互联网上的服务器,目标MAC是什么? 很多小伙伴在刚学习网络协议的时候,经常这样直接回应:不就是服务器的MAC嘛! 这时我会反问:那电脑怎么拿到这个服务器的MAC地 ...
- 简析ThreadLocal原理及应用
简析ThreadLocal原理及应用 原创: 东晨雨 JAVA万维猿圈 4月17日 ThreadLocal的源码加上注释不超过八百行,源码结构清晰,代码也比较简洁.ThreadLocal可以说是Jav ...
- Excel数据分析 --数据透析表
数据透析表主要用于各种数据总汇,对各项数据指标进行分类统计 实例分析 如下所示:是一份销售流水数据,有时间,地区,销售员,商品名称,数量,单价和金额几个字段,如下所示: 现在针对不同的数据汇总需求,可 ...
- [转]CAP原理与最终一致性 强一致性 透析
在足球比赛里,一个球员在一场比赛中进三个球,称之为帽子戏法(Hat-trick).在分布式数据系统中,也有一个帽子原理(CAP Theorem),不过此帽子非彼帽子.CAP原理中,有三个要素: 一致性 ...
随机推荐
- WebApi 插件式构建方案:发现并加载程序集
插件式的 WebApi 开发,首要面对的问题就是程序集的发现.因为开发的过程中,都是在各自的解决方案下进行开发,部署后是分模块放在一个整体的的运行时网站下. 约定 这里我根据上一节的设定,把插件打包完 ...
- solr-4.10.2版本使用tomcat7部署
当前版本仅限于solr-4.10.2版本.默认环境使用的是jdk1.7,tomcat7.环境自己配置.网上一堆堆的. 1.下载相应的文件(solr-4.10.2.zip). 官网地址:http://l ...
- thinkphp3搜索结果分页
公司的办公室搬到武昌,办公室水不好喝 还是乐百氏 娃哈哈的水我们oa用的tp3的一套oa,现在boss要求按状态 和类型(2个维度)来搜索案子 数量多,用 分页注意到初始的表单 input的name ...
- 洛谷P5292 [HNOI2019]校园旅行(二分图+最短路)
题面 传送门 题解 如果暴力的话,我们可以把所有的二元组全都扔进一个队列里,然后每次往两边更新同色点,这样的话复杂度是\(O(m^2)\) 怎么优化呢? 对于一个同色联通块,如果它是一个二分图,我们只 ...
- 使用X-Pack插件来进行权限控制
1.为elasticsearch安装X-Pack插件.进入 elasticsearch根目录,执行: bin/elasticsearch-plugin install x-pack杀掉进程,重启es, ...
- mxonline实战10,课程列表页,课程详情页1
对应github地址:第10天 一. 课程列表页 1. 拷贝course-list.html到templates目录中 2. 编写url和view 在courses/views.py中新加
- c++之随堂笔记
1.指针篇 给指针赋值时,只能等号右边只能使用&符号将一个对象的地址赋值给指针,不能直接把一个具体的数或者字符串直接赋值给指针. 举例: int* ptr_num = 100; //这种写法 ...
- 阿里巴巴前端面试分享-社招(p6)
借鉴了朋友的阿里面试经:(社招前端2年经验) 电话面 简单自我介绍, 做过哪些项目, 使用哪些技术栈 ? 如何看待前端框架选型 ? vue的如何实现双向绑定的 ? react 虚拟DOM 是什么? 如 ...
- shell-008:检测502
检测502的方法有多种 1.curl他的状态码(不建议,会对网站造成不必要的访问和多余的日志输出) 2.可以直接检测访问日志 下面用while做成一个死循环监控日志502的状态 #!/bin/bash ...
- Dijkstra+优先队列 堆优化
关于堆优化 传统\(Dijkstra\),在选取中转站时,是遍历取当前最小距离节点,但是我们其实可以利用小根堆(STL的priority_queue)优化这个过程,从而大大降低复杂(\(O(V2+E) ...