【计算机网络】详解网络层(二)ARP和RARP

ARP

ARP(Address Resolution Protocol,地址解析协议)是将IP地址解析为以太网MAC地址(物理地址)的协议。在局域网中,当主机或其他网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即IP地址)。但是仅仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过物理网络发送。因此发送方还需要有接收方的物理地址,也就需要一个从IP地址到物理地址的映射,ARP就是事先这么功能的协议。

1、ARP报文格式

ARP是一个独立的三层协议,所以ARP报文在此数据链路层传输时不需要经过IP协议的封装,而是直接生成自己的报文,其中包括ARP报头,到数据链路层后再由对应的数据链路层协议进行封装。ARP报文分为ARP请求和ARP应答报文两种,二者格式可以统一用下图表示:

硬件类型,表示ARP报文可以在哪种类型的网络上传输

上层协议类型,表示硬件地址要映射的协议地址类型

操作类型,指定本次ARP报文类型(请求/应答)

ARP报文并不是直接在网络层上发送的,它还是需要向下传输到数据链路层,所有当ARP报文传输到数据链路层后,需要再次进行封装。在以太网中,ARP传输到数据链路层后会封装成ARP帧。其格式如下图所示

可以看出,其帧封装都是一样的,网络层的直接作为数据链路层帧的数据部分。

目的MAC地址,如果是ARP请求帧,因为它是一个广播帧(后面会介绍),所以要填上广播MAC地址——FF-FF-FF-FF,其目标为网络上的所有主机

源MAC地址,发送ARP帧的节点MAC地址

帧类型,标识帧封装的上层协议

2、ARP映射表

无论是主机,还是交换机都会有一个用来缓存同一网段设备IP地址和MAC地址的ARP映射表,用于数据帧的转发。设备通过ARP解析到目的MAC地址后,将会在自己的ARP映射表中增加IP地址到MAC地址的映射表项,以用于后续到同一目的地数据帧的转发。

ARP表项分为动态ARP表项和静态ARP表型。

3*、ARP地址解析原理

  1. 主机A首先查看自己的ARP表(一个IP地址与MAC地址的映射表),确定其中是否包含有主机B的IP地址和对应的MAC地址。如果找到了对应的MAC地址,则主机A直接利用ARP表中的MAC地址对IP数据报进行帧封装,并将数据报发送给主机B。类似于计算机组成中高速缓存的命中。
  2. 如果主机A在ARP表中找不到对应的MAC地址,则先缓存该数据报文,然后以广播方式(参见数据链路层物理地址寻址部分,目的MAC地址为广播MAC地址——FFFFFF,任一同网段的节点均可收到,该网络上的所有主机)发送一个ARP请求报文,ARP请求报文中的发送端(源)IP地址和发送端MAC地址分别为主机A的IP地址和MAC地址,目的IP地址和目的MAC地址为主机B的IP地址和全0的MAC地址。ARP请求报文是以广播的形式发送,所以该网段上的所有主机都会接收到这个请求包,但只有其IP地址与目的IP地址一致的主机B会对该请求进行处理。
  3. 主机B将ARP请求报文中的发送端(主机A)的IP地址和MAC地址存入自己的ARP表中,然后以单播方式(一对一,点对点形式)向主机A发送一个ARP响应报文,应答报文中就包含了自己的MAC地址,即原来请求报文中要请求的MAC地址。
  4. 主机A在收到来自主机B的ARP响应报文后,将主机B的MAC地址加入到自己的ARP表中以用于后续报文的转发,同时将原来缓存的IP数据报再次修改(在目的MAC地址子弹填上已获得的主机B的的MAC地址)后发送出去。

上面就是同一网段中两主机的ARP地址解析的全过程。当两主机不在同一个网段中,其ARP地址解析过程如下:

  1. 如果主机A不知道网关(一个网络连接另一个网络的关口)的MAC地址(即主机A的ARP表没有命中),则主机A现在本网段中发出一个ARP请求广播报文,ARP请求报文中的目的IP地址为网关IP地址,代表其目的就是想获得网关的MAC地址。如果主机A已知网关MAC地址,则略过此步。
  2. 如果网关的ARP表(网关也有ARP映射表项)中已有主机B对应的MAC地址,则网关直接将在来自主机A的报文中的目的MAC地址字段填上主机B的MAC地址后转发给主机B。
  3. 如果网关ARP中没有,那么网关会再次向主机B所在网段发送ARP广播请求报文,此时目的IP地址为主机B的IP地址,其后续处理同前。

可以看出,不在一个网段的两个主机的ARP地址解析过程实际上是拆分为两个网段中的ARP地址解析过程,只不过介入一个网关充当主机。

这里说一下网关,网关实质上是一个网络通向其他网络的IP地址,是一个逻辑概念,定义网络的边界。路由器是物理设备,除具备网关功能外,还具备路由功能(以后再说)。

比如说只有两个网络,网络A(192.168.1.1~192.168.1.254)和网络B(192.168.2.1`192.168.2.254),子网掩码为255.255.255.0。可以看出这两个网络属于不同的两个网络,不能直接进行通信。即使连接在同一台交换机上,TCP/IP协议也会根据子网掩码判定两个网络中的主机处于不同网络里,不能进行网络间通信。(交换机是在物理层上工作,按MAC地址访问,所以也称二层交换机,两个子网间不能互访,除非是具备路由功能和VLAN功能的三层交换机)。这种情况下则需要通过网关进行通信。因为只有两个网络,也就一条连接路径,所以只需要网关就可以。

但如果是多个网络结构,形成一个网状,即两个网络之间可以有多条访问路径,这样则需要网关和路由器两种设备,不过现在路由器已经继承了网关的功能,所以只需要一个路由器即可,利用路由器的路由功能选择最佳路径进行通信。

RARP

RARP分组的格式与ARP分组基本一致。RARP为逆地址解析协议,作用与ARP相反,用于将MAC地址转换为IP地址。

具有本地磁盘的系统引导时,一般是从磁盘上的配置文件中读取IP地址,但是无盘机,如X中断或无盘工作站,则需要采用其他方法来获得IP地址。

总得说来就是,网络上的每个系统都具有唯一的硬件地址,它是由网络接口生产厂家配置的。无盘系统的RARP实现过程是从接口卡上读取唯一的硬件地址,然后发送一份RARP请求,请求某个主机响应该无盘系统的IP地址。

RARP的工作过程如下:

  1. 网络上每台设备都会有一个独一无二的硬件地址,一般是由设备厂商分配的MAC地址。发送主机从网卡上读取MAC地址,然后在网络上发送一个RARP请求的广播数据包,请求任何收到此请求的RARP服务器分配一个IP地址;
  2. RARP服务器收到此请求后,检查其RARP表项,查找该MAC地址对应的IP地址;
  3. 如果存在,RARP服务器就给发送主机回复一个响应数据包,并将此IP地址提供给对方主机使用;
  4. 如果不存在,RARP服务器对此不做任何的响应;
  5. 发送主机收到从RARP服务器的响应信息,就利用得到的IP地址进行通讯,如果一直没有收到RARP服务器的响应消息,表示初始化失败。

需要清楚,与ARP不同的是RARP是主机向RARP服务器获取自己的IP地址。

RARP从概念上看起来比较简单,但实际上比较复杂,服务器一般要为多个主机提供硬件地址到IP地址的映射,该映射包含在一个磁盘文件中,而内核一般不读取和分析磁盘文件,所以RARP服务器的功能就需由用户进程来提供。更为复杂的是,RARP请求是作为一个特殊类型的以太网数据帧来传送的,其请求是在硬件层上进行广播的,不经过路由器进行转发。

RARP协议是许多无盘系统在引导时用来获取IP地址的,一个RARP请求在网络上进行广播,它在分组中表明发送端的MAC地址,以请求相应IP地址的响应。另外RARP服务器的实现与系统相关。

对应于ARP,RARP请求是以广播方式发送,而ARP,RARP应答则一般是单播传送的。

关于ARP地址解析过程的源码剖析参见博文【Linux 内核网络协议栈源码剖析】ARP地址解析协议

参考资料:

《深入理解计算机网络》、《TCP/IP 一》。

时间: 2024-09-27 05:10:18

【计算机网络】详解网络层(二)ARP和RARP的相关文章

[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透                ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)                [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]

logback logback.xml常用配置详解(二)<appender>

logback 常用配置详解(二) <appender> <appender>: <appender>是<configuration>的子节点,是负责写日志的组件. <appender>有两个必要属性name和class.name指定appender名称,class指定appender的全限定名. 1.ConsoleAppender: 把日志添加到控制台,有以下子节点: <encoder>:对日志进行格式化.(具体参数稍后讲解 ) &

logback 常用配置详解(二) &lt;appender&gt;

logback 常用配置详解(二) <appender> <appender>: <appender>是<configuration>的子节点,是负责写日志的组件. <appender>有两个必要属性name和class.name指定appender名称,class指定appender的全限定名. 1.ConsoleAppender: 把日志添加到控制台,有以下子节点: <encoder>:对日志进行格式化.(具体参数稍后讲解 ) &

【Hibernate步步为营】--双向关联一对一映射详解(二)

很不好意思,有两天时间没有更新博客文章了,不写文章的日子还真是感觉很空洞啊,养成了写文章的恶习想改也改不掉啊.说点题外话,前两天收到一位朋友的私信,邀请笔者写一篇有关OWS的文章,用来研究图标工具的一种技术,很荣幸收到这位朋友的邀请,但是因为这几天开发的项目着急上线所以暂时没有时间去研究,只能等这周末了,利用周末的时间来研究然后更新类似的技术文章. 回到文章的正题,上篇文章讨论了双向主键关联,它其实是一对一主键关联的一种特殊情况,想要实现双向的关联就必须在映射文件的两端同时配置<one-to-o

iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

这里接着前文<iOS 开发之照片框架详解之二 —— PhotoKit 详解(上)>,主要是干货环节,列举了如何基于 PhotoKit 与 AlAssetLibrary 封装出通用的方法. 三. 常用方法的封装 虽然 PhotoKit 的功能强大很多,但基于兼容 iOS 8.0 以下版本的考虑,暂时可能仍无法抛弃 ALAssetLibrary,这时候一个比较好的方案是基于 ALAssetLibrary 和 PhotoKit 封装出一系列模拟系统 Asset 类的自定义类,然后在其中封装好兼容 A

iOS 开发之照片框架详解之二 —— PhotoKit 详解(上)

一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLibrary 封装出通用的方法. 这里引用一下前文中对 PhotoKit 基本构成的介绍: PHAsset: 代表照片库中的一个资源,跟 ALAsset 类似,通过 PHAsset 可以获取和保存资源 PHFetchOptions: 获取资源时的参数,可以传 nil,即使用系统默认值 PHAssetCo

安卓集成发布详解(二)gradle

转自:http://frank-zhu.github.io/android/2015/06/15/android-release_app_build_gradle/ 安卓集成发布详解(二) 15 Jun 2015 上一篇主要讲了安卓版本编译版本发布的过程,本篇主要写版本编译脚本的实现,包括签名文件处理及多渠道版本编译.安卓集成发布详解(一) 一.签名部分编写 gradle本身支持直接签名,只需要在releas部分添加如下代码即可 signingConfigs { debug { } releas

cocoahttpserver使用详解(二)

接下来,我们接着去学习如何去接收处理web上传的数据 1 首先我们创建一个 @interface WTZHTTPConnection : HTTPConnection 在这个类中我们用于处理接受文件并存储到app文档 同时不要忘记了设置httpserver的Connectio类 [httpServer setConnectionClass:[WTZHTTPConnectionclass]]; 全部的代码如下 .h文件 #define UPLOAD_FILE_PROGRESS @"uploadfi

Tomcat--各个目录详解(二)

Tomcat整体目录: 一.bin文件(存放启动和关闭tomcat脚本) 其中.bat和.sh文件很多都是成对出现的,作用是一样的,一个是Windows的,一个是Linux. ① startup文件:主要是检查catalina.bat/sh 执行所需环境,并调用catalina.bat 批处理文件.启动tomcat. 异常:打开可能有闪退的问题.原因可能有以下两点: 1)缺少环境变量配置,startup会检查你的电脑环境变量是否有JAVA_HOME. 2)已经开启了Tomcat容器,再次开启端口

log4j详解(二)

在实际编程时,要使Log4j真正在系统中运行事先还要对配置文件进行定义.定义步骤就是对Logger.Appender及Layout的分别使用.Log4j支持两种配置文件格式,一种是XML格式的文件,一种是java properties(key=value)[Java特性文件(键=值)].(这里只说明properties文件) 1.配置根Logger         其语法为:         log4j.rootLogger = [ level ] , appenderName1, append