大家好,我是风筝。

各位同学肯定见过关于网络的面试题,什么TCP协议和UDP的区别啦,IP协议工作在哪层啊等等,这都是网络中定义的各种协议。这些标准化的协议就是网络分层模型标准化的核心部分。要想搞懂网络,必须搞明白其中的几种主要的网络协议。

今天我们就开始介绍网络世界的协议。介绍的顺序大致是从网络模型由底向上来,包括数据链路层的以太网协议,网络层的 ARP协议、RARP协议、IP协议、ICMP协议,传输层的 TCP协议、UDP 协议,以及应用层的 HTTP/HTTPS协议。

我们假设数据包都是在以太网传输,所以以太网协议一直是贯穿始终的,因为最终所有的数据包都会被封装成以太网帧,所以其他几种协议的介绍过程中,会穿插这以太网协议,不用单独介绍,自然而然就理解了。

今天我们就彻底讲清楚 ARP 协议(地址解析协议), 我把 ARP 协议比作数据包在网络世界的临门一脚,当数据包到达了一个局域网中,局域网中有那么多机器,踢开哪台机器的大门,就靠 ARP 协议了。为什么这么说,一会儿你就明白了。

其实 ARP 协议可以简单概括为几句话:

  1. ARP 工作在局域网内;
  2. ARP 的作用是根据 IP 地址获取对应的 MAC 地址;
  3. 在网络中最终传输的数据叫做数据帧,是数据链路层最后封装的,而数据帧要根据 MAC 地址找到目的主机,一般是目的主机的某个网卡;
  4. 而一般我们只知道目的主机的 IP,不知道 MAC 地址,所以需要 ARP 协议。

好的,讲完了。开个玩笑,当然没有,最好还是继续看下边的内容。

在 OSI 模型中,通常认为 ARP和RARP属于数据链路层协议,因为它们不使用IP协议。而在TCP/IP 协议栈中,将 ARP归于网络层,和IP协议在同一层。

只要知道对方的 IP 地址或域名,就能将数据发送过去,这是我们常识性的理解。而且在平常的使用过程中也确实是这样的。比如我们开发过程中,建立一个 socket 连接,只要知道目标 IP 和 端口就可以了。

真实的网络世界中是这样的吗,确实 IP 地址是必不可少的,但是还有另外一种地址也是必不可少的,那就是 MAC 地址。

最终,在数据到达以太网链路层,会被包装成以太网数据帧,而数据帧中决定最终去向的是就是目标 MAC 地址,注意喽,是 MAC 地址(硬件地址),而不是 IP 地址。

可以把 IP 比作现实世界中一个房子的标记,比如北京市朝阳区XX路xx小区1号楼1单元801,而 MAC 地址则是这个房子的经纬度(116.354856,39.942009),虽然我们看前面的一串标示更容易理解,但是当我们要导航去那里的时候还是要靠经纬度。

但是如何在一大群机器中确定目标 IP 对应的 MAC 地址呢,数据已经到了局域网,这么多大门该开哪一扇呢,这就是 ARP 该做的事儿了。

什么是 MAC 地址

MAC地址(Media Access Control Address),直译为媒体存取控制位址,也称为局域网地址(LAN Address),以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网路设备位置的位址。在OSI模型中,第三层网路层负责IP地址,第二层资料链结层则负责MAC位址。MAC地址用于在网络中唯一标示一个网卡,一台设备若有一或多个网卡,则每个网卡都需要并会有一个唯一的MAC地址。

MAC 地址长度为6字节,48bit,用16进制的6个元组表示,例如 3c:22:fb:64:4f:1d,其中有一个特殊的地址就是所有比特位都是1的地址 ff:ff:ff:ff:ff:ff,表示是一个广播地址,意思就是指消息要发给局域网中的所有网卡。

为什么需要 ARP 协议

直接的原因就是数据链路层要将数据帧发送到目的端,必须要知道目的端的 MAC 地址,这是由网络模型的架构设计决定的。

下面这张图是网络 4 层模型以及数据从发送端到接收端的首发过程。发送是从上向下经过层层包装,最后形成一个数据帧(最常用的以太网帧),之后这个数据在纷繁复杂的网络世界中勇往直前,到达接收端,接收端从下向上层层拆包,最后供应用层使用。

上面这张图很有用的,在学习网络知识(不管是基础概念还是各种协议)的时候可以为我们提供一个宏观的视角。

网络中的设备数以亿计,一个发送终端怎么可能知道每一台接收终端的 MAC 地址呢,显然,这是不可能的。但是 IP 是知道的,比如我们访问 github,github 每一台服务器的 MAC 地址(准确的说是一个网卡的 MAC 地址,因为一台机器上可能有多个网卡)我们是不知道的,但是它的域名我们都知道,通过域名得到 IP 地址,这是 DNS 的功能,大多数同学都很清楚,所以间接的也就相当于我们知道了 github 的IP。

但是,为什么我们在做应用层开发的时候不需要关注 MAC 地址。

根本没有什么岁月静好,只是有人在替我们负重前行罢了。在这里帮我们负重前行的就是 ARP 协议。

这里面有一个关键点,最终在网络上传输的包,必定是一个数据帧,最常用的就是以太网帧。

如果我们完全将这一过程当做一个黑盒,可以对照理解为一个程序中封装好的方法,例如 getMacAddressByIP(Long ip) ,当我们需要得到 MAC 地址时,直接调用这个方法就可以了。

ARP 协议全称地址解析协议,用来将 IP 地址解析出 MAC 地址,还有一个与之相对的协议 RARP,全称叫做逆地址解析协议,用来将 MAC 地址解析出 IP 地址。

ARP 的工作过程

ARP 就是工作在一个局域网中的,

当一台路由器或者一个具有路由转发功能的主机想要通过一个 IP 地址得到对应的 MAC 地址时,就可以使用 ARP 协议了,这个设备向它所在的目标子网中发送一个广播的 ARP 请求,请求中带着这个 IP 地址,意思是说,在这个网络中的各位,谁的 IP 是这个,请回复我一下,并告诉我你的 MAC 地址。收到这个请求的主机对这个 ARP 包进行解析,如果发现携带的 IP 正好是自己的,就返回一个 ARP 回复,回复中带上自己的 MAC 地址。

使用 ARP 协议后,目的主机将自己的 IP 地址和 MAC 地址返回给源主机,源主机将 MAC 地址加到以太网帧中,构造成完整的帧格式,再将数据帧通过链路层发出。

最终数据帧到达目的主机,链路层通过数据帧中的目的 MAC 地址判断数据帧是不是发给自己的,如果是的话,则接收数据帧,并经过层层解析,最终交给应用层对应的程序处理。

先说说以太网数据帧格式

以太网目的地址:目的端 MAC 地址,6字节。

以太网源地址:发送端的 MAC 地址,6字节。

帧类型:标记数据部分的类型,如果是 IP 数据报,值为 0x0800,如果是 ARP 数据报,值为 0x0806,2字节。

数据:以太帧搭载的数据。只要是在以太网上发送数据,最终都会被链路层封装成以太网数据帧,所以数据部分即可以是 IP 数据报、ARP 协议包、ICMP 数据包等,以太网数据帧数据部分最小长度是 46 字节,最大长度由 MTU 决定,是 1500 字节。

CRC:数据检验码,用来在接收端检验接收的数据是不是无差错的,4字节。

既然大家都是程序员,我们将这个数据帧抽象成一个实体类表示,帮助我们理解。

public class EthernetFrame {
/**
* 目的 MAC 地址,6字节,48bit
*/
private Byte[] destinationMacAddress = new Byte[6]; /**
* 源 MAC 地址,6字节,48bit
*/
private Byte[] sourceMacAddress = new Byte[6]; /**
* 标记搭载的数据类型,
* 如果是 IP 数据报,值为 0x0800
* 如果是 ARP 数据报,值为 0x0806
*/
private Byte[] type = new Byte[2]; /**
* 数据
* 以太网的数据长度为 46~1500字节。
* 最短 46 字节,不够的要填充(pad)
* 最长 1500 字节,以太网的 MTU 决定的
*/
private Byte[] data = new Byte[46]; /**
* 检验码 4 字节,在帧尾部
*/
private Byte[] crc = new Byte[4];
}

ARP 协议格式

以下是 ARP 协议的格式,以及一对完整的 ARP 请求数据帧和应答数据帧。

硬件类型:2字节,用来表示硬件地址的类型,为 1 表示以太网地址。

协议类型:2字节,用来表示要映射的协议地址类型。ARP 不仅可以表示要将 IP 转换为 MAC ,还允许其他的转换关系,例如将另外一种非 IP 地址转换为 MAC 地址。当它的值为0x0800表示 IP 地址,与包含IP数据报的以太网数据帧中的类型字段的值相同。

硬件地址长度:1字节,用来表示硬件地址的长度,单位是字节。在以太网中就是 MAC 地址的长度,值为6,也就表示 MAC 地址长度为 6 字节。

协议地址长度:1字节,用来表示协议地址的长度,单位是字节。在以太网中,如果协议类型是 IP,也就是要将 IP 转换为 MAC 时,它的值是 4 ,也就是4字节,表示 IP 地址的长度是 4 字节。

操作字段:2字节,用来表示当前操作的类型。值为1,表示 ARP 请求;值为2,表示 ARP 应答;值为3,表示 RARP 请求;值为4,表示 RARP 应答。此字段是用来区分请求和应答的必需字段。

发送端以太网地址:6字节,用来表示发送端的以太网 MAC 地址。

发送端 IP 地址:4字节,用来表示发送端的 IP 地址。

目的以太网地址:6字节,用来表示目的端的 MAC 地址。

目的 IP 地址:4字节,用来表示目的端的 IP 地址。

整个 ARP 协议部分共 28字节,但是在以太网中,一个以太网数据帧数据最小长度为 46,所以,后面要有18字节的数据填充。

操作字段为1表示这是一个 ARP 请求,ARP 请求是个广播消息,请求数据中没有目的 MAC 地址,因为还不知道嘛,我们要找的就是它。之后,ARP 应答消息(操作字段是2)将本机的 MAC 地址放到源MAC地址中,并且将 ARP 请求中的MAC地址替换为目的 MAC 地址,用来告知 ARP 发送端。

还是用一个实现类来表示 ARP 协议中的各个字段。

public class Arp {
/**
* 硬件类型,2字节,值为1表示以太网
*/
private Byte[] hardwareType = new Byte[2]; /**
* 协议类型,2字节,要映射的协议地址类型
* 0x0800 表示要转换的源协议为 IP 协议
*/
private Byte[] protocolType = new Byte[2]; /**
* 硬件地址长度,1字节,表示硬件地址的长度,单位为字节
* 硬件地址长度在以太网表示 MAC 地址的长度,值为6,也就是 6 字节
*
*/
private Byte[] hardwareAddressLength = new Byte[1]; /**
* 协议地址长度,1字节,表示协议地址的长度,单位为字节
* 在以太网转换 IP 为 MAC 地址时,就表示为 IP 地址的长度,也就是4字节
*/
private Byte[] protocolAddressLength = new Byte[1]; /**
* 操作字段,2字节,表示操作类型
* 1:ARP 请求
* 2:ARP 应答
* 3:RARP 请求
* 4:RARP 应答
*/
private Byte[] op = new Byte[2]; /**
* 发送端 MAC 地址,6字节
*/
private Byte[] sourceMacAddress = new Byte[6]; /**
* 发送端 IP 地址,4字节
*/
private Byte[] sourceIpAddress = new Byte[4]; /**
* 目的端 MAC 地址,6字节
* 在 ARP 请求中,这个地址为空
*/
private Byte[] destinationMacAddress = new Byte[6]; /**
* 目的端 IP 地址,4字节
* 接收 ARP 广播的主机通过 IP 地址判断是否回复 ARP 应答(IP 地址的所有者)
*/
private Byte[] destinationIpAddress = new Byte[4];
}

用 Wireshark 抓个包

打开 Wireshark ,开始抓包,等待一会儿,然后停止抓包。你电脑中的各个程序会偷偷的发送和应答很多 ARP 包,

在 Wireshark 中过滤 arp.opcode == 1的 ARP 请求,然后找到其中一个。用 Wireshark 分析包特别直观,我们用鼠标点击上方的某个字段时,下面会自动将这个字段的值标记出来,这样就可以清楚的看到这个字段在整个数据包中的位置了。例如下图选中了 ARP 包中的 Opcode字段(操作字段),下面的 00 01 被标记了,这是用 16 进制表示的,00表示一个字节,01表示一个字节,表示这个操作字段是2个字节,值是1,也就是ARP 请求。

简单分析一下这个包

图中 1、2、3 三个部分分别是以太网帧概要信息、以太网数据帧首部、以太网数据帧数据内容。在第一部分概要信息可以看到这个帧的总大小是 60 bytes,以太网数据帧头部的14 字节,加上内容部分最少46字节,刚好是 60 字节,其实还有一个 CRC (数据检验码),只不过本地网卡会自动剥离掉,所以在 Wireshark 中是看不到的。

以太网数据帧首部

上图是以太网数据帧首部信息。

1、目的 MAC 地址,都是 ff,表示这是个广播请求,ARP 请求本身就是广播的。

2、源 MAC 地址,本机的 MAC 地址。

3、帧类型,ARP 类型。

4、因为以太网帧数据部分最小是 46 字节,ARP 只有28字节,所以要填充18字节。

ARP 请求信息

从上到下依次是硬件类型、协议类型、硬件地址长度、协议地址长度(一般就是IP地址)、操作字段、发送端 MAC 地址、发送端 IP 地址、目标 MAC 地址、目标 IP 地址。

使用 wireshark 的 filter arp.opcode == 2 可过滤出 APR 请求。

是不是完全听明白了,回头发现,就是我开头总结的那几点内容。

自己学容易,写出来真难啊,如果对各位有一点点帮助当然最好了。


如果觉得还不错的话,给个推荐吧!

公众号「古时的风筝」,Java 开发者,专注 Java 及周边生态。坚持原创干货输出,你可选择现在就关注我,或者看看历史文章再关注也不迟。长按二维码关注,跟我一起变优秀!

ARP协议:网络世界的临门一脚的更多相关文章

  1. 图解ARP协议(五)免费ARP:地址冲突了肿么办?

    一.免费ARP概述 网络世界纷繁复杂,除了各种黑客攻击行为对网络能造成实际破坏之外,还有一类安全问题或泛安全问题,看上去问题不大,但其实仍然可以造成极大的杀伤力.今天跟大家探讨的,也是技术原理比较简单 ...

  2. Winpcap网络编程九之Winpcap实战,ARP协议获得MAC表及主机通信

    大家好,本次我们须要完毕的任务是: 完毕两台主机之间的数据通信(数据链路层) 仿真ARP协议获得网段内主机的MAC表 使用帧完毕两台主机的通信(Hello! I'm -) 声明:本文章的目的是为大家的 ...

  3. 网络协议 16 - DNS 协议:网络世界的地址簿

    [前五篇]系列文章传送门: 网络协议 11 - Socket 编程(下):眼见为实耳听为虚 网络协议 12 - HTTP 协议:常用而不简单 网络协议 13 - HTTPS 协议:加密路上无尽头 网络 ...

  4. 【网络协议】IP协议、ARP协议、RARP协议

    IP数据报 IP是TCP/IP协议族中最核心的协议,全部的TCP.UDP.ICMP.IGMP数据都以IP数据报的格式传输.IP仅提供尽力而为的传输服务.假设发生某种错误.IP会丢失该数据.然后发送IC ...

  5. 网络基础:ARP 协议、IP协议、路由协议 均属于网络层协议

    ARP协议 ARP--地址解析协议(Address Resolution Protocol),实现通过 对方的IP地址(域名) 寻找对方的 MAC地址 ARP的功能 本地电脑查看 IP 和 MAC 对 ...

  6. 三分钟网络基础-ARP协议

    什么是 ARP 协议 地址解析协议 ARP (Address Resolution Protocal):在同一局域网下,根据已知道的主机或路由器的 IP 地址,找出其相应的硬件地址. 高速缓存 每一个 ...

  7. [图解]ARP协议(一)

    一.ARP概述 如果要在TCP/IP协议栈中选择一个"最不安全的协议",那么我会毫不犹豫把票投给ARP协议.我们经常听到的这些术语,包括"网络扫描"." ...

  8. 图解ARP协议(三)ARP防御篇-如何揪出“内鬼”并“优雅的还手”

    一.ARP防御概述 通过之前的文章,我们已经了解了ARP攻击的危害,黑客采用ARP软件进行扫描并发送欺骗应答,同处一个局域网的普通用户就可能遭受断网攻击.流量被限.账号被窃的危险.由于攻击门槛非常低, ...

  9. 浅谈ARP协议以及应用

    0. 前言 本章主要简单的介绍ARP的协议格式,主机如何发送和处理ARP报文,以及免费ARP. 1. ARP协议原理 ARP,全称Address Resolution Protocol,地址解析协议, ...

  10. 6410实现网卡(DM9000A)收发功能及ARP协议实现

    1. 网卡硬件结构(DM9000A) 网卡的实质就是MAC通过MII接口控制PHY的过程. MAC主要负责数据帧的构建.数据差错检查.传送控制等. PHY是物理接口收发器,属于物理层,当它收到MAC过 ...

随机推荐

  1. css实现图片在div中居中的效果

    利用图片的margin属性将图片水平居中,利用div的padding属性将图片垂直居中. 结构代码同上: css代码如下: div {width:300px; height:150px; paddin ...

  2. Apache Geronimo默认管理密码

    网络空间资产搜索: FoFa 弱口令:system/manager 登陆成功! End!!!

  3. phpExcel常用方法详解

    phpExcel常用方法详解[附有php导出excel加超级链接] 发表于4年前(2012-07-20 12:57) 阅读(510) | 评论(0) 0人收藏此文章, 我要收藏 赞0 http://w ...

  4. 解决方案-Jmeter在CLI模式下无法生成html报告文件

    出错场景: 在CLI模式下运行jmeter,将 jtl 结果转为 html 报告时,提示An error occurred: Data exporter "html" is una ...

  5. Guava布隆过滤器实战应用

    布隆过滤器 简介:本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 "某样东西一定 ...

  6. PTA1003 我要通过! (20 分)

    PTA1003 我要通过! (20 分) "答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 -- 只要读入的字符串满足下 ...

  7. asm 理解

    stm32中有3条总线:地址总线,数据总线,系统总线:地址总线上是地址值,数据总线上是数据值,cpu读写时会先在地址总线上传输地址值,如果是写操作之后数据总线上会放往前面地址处写入的数据值,如果是读操 ...

  8. 网易二面-Arthas的底层原理

    众所周知,阿里开源的Arthas已经成为Java开发中调优的基本工具,其功能在于监控JVM运行情况,并对CPU.内存状况生成报告或者是火炬图. 从JDK5开始,java.lang.instrument ...

  9. python+基本3D显示

    想要将双目照片合成立体图实现三维重建,完全没有头绪.但是对三维理解是必须的.所以将以前在单片机上运行的 3D画图 程序移植到python上.效果如下: 没有用numpy.openGL等,只用了纯mat ...

  10. NOIP2012普及组

    T2]寻宝 读懂题目!! 是逆时针,第几个有钥匙的房间,还有能够直接上楼的是作为第一个有钥匙的房间,而不是就从这里直接上楼了 #include<iostream> #include< ...