交换机开发(四)—— ARP 基础知识解析

一、ARP协议简介 

     Internet是由各种各样的物理网络通过使用诸如路由器之类的设备连接在一起组成的。当主机发送一个数据包到另一台主机的过程中 可能要经过多种不同的物理网络。主机和路由器都是在网络层通过IP地址来识别的,这个地址是在全世界内唯一的。 然而,数据包是通过物理网络传递的。在物理网络中,主机和路由器通过其MAC地址来识别的,其范围限于本地网络中。 MAC地址和IP地址是两种不同的标识符。这就意味着将一个分组传递到一个主机或路由器需要进行两级寻址:IP和MAC。需要能将一个IP地址映射到相应的MAC地址

     ARP协议是“Address Resolution Protocol”(地址解析协议)的缩写。 所谓“地址解析”就是主机在发送帧前将目标网络层地址转换成目标物理地址的过程。在使用TCP/IP协议的以太网中,即完成将IP地址映射到MAC地址的过程——使用ARP协议通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。


二、ARP报文格式

     从网络底层看来,一个ARP包是分为两个部分的,前面一个是物理帧头,后面一个才是ARP帧

  首先,物理帧头,它将存在于任何一个协议数据包的前面,我们称之为DLC Header,因为这个帧头是在数据链路层构造的,并且其主要内容为收发双方的物理地址,以便硬件设备识别。

DLC Header
字段
长度(Byte)
默认值
备注
接收方MAC
6
广播时,为 ff-ff-ff-ff-ff-ff
发送方MAC
6
Ethertype
2
0x0806
0x0806是ARP帧的类型值

                                                图1 物理帧头格式

     图1是需要我们填充的物理帧头的格式,我们可以看到需要我们填充的仅仅是发送端和接收端的物理地址罢了,是不是很简单呢?

    接下来我们看一下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个字节

                                                图2 ARP帧格式

我们可以看到需要我们填充的同样也只是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就填充完成了,如图,加粗的是我们要手动输入的值(当然我编的程序比较智能,会根据你选择的ARP包类型帮你自动填入一些字段,你一用便知)。

DLC Header
字段
长度(Byte)
填充值
接收方MAC
6
ffffffffffff
发送方MAC
6
aaaaaaaaaaaa
Ethertype
2
0x0806

                                                图3 ARP请求包中 DLC Header内容

        接下来是ARP帧,请求包的操作码当然是 1,发送方的MAC以及IP当然填入我们自己的,然后要注意一下,这里的接收方IP填入我们要查询的那个IP地址,就是192.168.0.99了,而接收方MAC填入任意值就行,不起作用,于是,如图

ARP Frame
字段
长度(Byte)
填充值
硬件类型
2
1
上层协议类型
2
0800
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

                                               图4 ARP请求包中 ARP帧的内容

       如果我们构造一个这样的包发送出去,如果 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,就是如此来填充各个字段

DLC Header
字段
长度(Byte)
填充值
接收方MAC
6
bbbbbbbbbbbb
发送方MAC
6
aaaaaaaaaaaa
Ethertype
2
0x0806

                                                图5 ARP响应包中 DLC Header内容

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

                                               图6 ARP响应包中 ARP帧的内容

这样192.168.0.99的ARP缓存中就会多了一条关于我们192.168.0.1的地址映射。


四、ARP的运行过程 

  在因特网中,数据报传递过程中包括如下步骤: 

1. 发送者知道目标端的IP地址 

2. IP要求ARP创建一个ARP请求报文,其中包含了发送方的物理地址、发送方的IP地址和目标端的IP地址。目标的物理地址用0填充。 

3. 将报文传递到数据链路层,并在该层中用发送方的物理地址作为源地址,用物理广播地址作为目的地址,将其封装在一个帧中。 

4. 同一链路中的每个主机或路由器都接收到这个帧,因为该帧中包含了一个广播目的地址,所有的站点都对报文进行移交,并将其传递到ARP。除了目标机器以外的所有机器都丢弃该报文。目标机器对IP地址进行识别。 

5. 目标机器用一个包含其物理地址的ARP响应报文做出响应,并对该报文进行单播。 

6. 发送方接收到一个响应报文,这样它就知道了目标机器的物理地址。 

7. 这样就可以将携带目标机器数据的IP数据报封装在一个帧中,并单播到目的地址。 


五、ARP缓存 

     实际上,在真正的协议实现中,并不是每次发送IP报文前都需要发送ARP请求报文来获取目的MAC地址。在大多数的系统中都存在着一个ARP缓存表。记录着已经获取的MAC地址和IP地址的映射关系,如下图:


          IP地址                    MAC地址 

      202.98.13.1      00-E0-4C-3D-89-76 

      202.98.13.2      00-E0-4C-3D-C5-03 

      202.98.13.3      00-E0-4C-4D-BA-92 
                ...                        ... 

     

       发送IP报文前总是先对ARP缓存表进行查找,看是否目标MAC地址存在于缓存表中,如果存在,则不需要发送ARP请求报文而直接使用此地址进行IP报文的发送。如果不存在,则发送ARP请求报文,并将结果存于ARP缓存表中供以后使用。 

     另外,ARP缓存表采用了老化机制,在一段时间内如果表中的某一行没有使用,就会被删除,这样可以大大减少ARP缓存表的长度,加快查询速度。 


六、ARP代理 

     ARP本身无法跨跃不同网段。当数据要发往外部网络时,通常是首先使用ARP请求网关路由器的MAC地址,之后将数据发往网关路由器, 由网关路由器进行转发(动画演示)。 但有时由于管理或地域等原因,我们的内部网络又会划分为很多子网,这时我们可以通过修改网络内每台主机的本地路由,使发往其它子网的数据发送到连接两个子网的路由器, 再由路由器转发。但这样也许并不是一个易于管理和维护的方案。我们可以使用ARP代理使子网的划分对每台主机更加透明化。ARP代理的工作原理很简单: 

      当ARP请求是从一个网络的主机发往另一个网络的主机时,启用ARP代理的连接这两个网络的路由器将回答该请求,使请求的发送者误以为此路由器就是目标主机, 而将所有数据帧发送到此路由器。路由器在收到数据帧后,再将其转发到真正的目标主机(动画演示)。 

     ARP代理实际上是使用了简单的欺骗手段,使网络内的主机错误的认为目标主机与自己处于同一网段内,从而达到了透明化子网划分的目的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VRP网络操作系统简介

VRP (Versatile Routing Platform)即通用路由平台,是华为在通信领域多年的研究经验结晶,是华为所有基于IP/ATM构架的数据通信产品操作系统平台。运行VRP操作系统的华为产品包括路由器、局域网交换机、ATM交换机、拨号访问服务器、IP电话网关、电信级综合…

Type mismatch:

Type mismatch: cannot convert from java.sql.PreparedStatement to com.mysql.jdbc.PreparedStatement import java.sql.PreparedStatement; java连接数据库的问题:Type mismatch: cannot convert from ResultSet to ResultSet 包导入错了,你要导入的是import jav…

Linux 下挂载新硬盘方法

Linux的硬盘识别: 一般使用”fdisk -l”命令可以列出系统中当前连接的硬盘 设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息. 1.关闭服务器加上新硬盘 2.启动服务器,以root用户登录 3.查看硬盘信息 #fdisk -l [cpp] view plaincopy Disk /dev/sda: 42.9 GB…

php面向对象之单表操作类

<?php //数据库单表操作类 define("HOST","localhost"); define("USER","root"); define("PASS",""); define("DBNAME","lamp78"); class Db {protected $link; //连接资源protected $…

C++ 学习基础篇(一)—— C++与C 的区别

编程的学习学无止境&#xff0c;只掌握一门语言是远远不够的&#xff0c;现在我们开始C的学习之路&#xff0c;下面先看下C 与C 的区别 一、C概述 1、发展历史 1980年&#xff0c;Bjarne Stroustrup博士开始着手创建一种模拟语言&#xff0c;能够具有面向对象的程序设计特色。在…

C++学习基础篇 —— 引用()的用法和应用

一、引用简介 引用就是某一变量&#xff08;目标&#xff09;的一个别名&#xff0c;对引用的操作与对变量直接操作完全一样。 引用的声明方法&#xff1a;类型标识符&引用名目标变量名&#xff1b; 【例1】&#xff1a; [cpp] view plaincopy int a; int &raa; //定义…

js 数组遍历for..in弊端

//for..in在数组中的弊端 原则上数组Array对象是不能操作的&#xff0c;但是有些程序员开始不注意把Array的原型链上添加了方法就会出现意想不到的bug//例如var arr [1,2,3];Array.prototype.test function() { }for(var i in arr) { //。。。。操作 }就会把test遍历出来 会出…

C++基础知识(一)—— C++程序结构

下面我们从一个最简单的程序入手看一个C程序的组成结构。 // my first program in C #include <iostream.h> using namespace std; int main() { cout << “Hello World!”; return 0; } Hello World! 上面左侧显示了我们的第一个程序的源代码&#xff0c…

给大家推荐一款高大上的代码高亮插件(sublime,github风格)——highlight.js

经常在一些大神博客里面看到非常好看的高亮代码&#xff0c;有sublime风格&#xff0c;GitHub风格等等。毫无疑问&#xff0c;好的高亮代码插件可以不仅仅让你的博文显得更高大上&#xff0c;更重要的是舒适的阅读体验。经过我在网上的一番搜罗&#xff0c;终于找到了一款非常赞…

C++基础知识(二)—— 变量和数据类型

你可能觉得这个“Hellow World”程序用处不大。我们写了好几行代码&#xff0c;编译&#xff0c;然后执行生成的程序只是为了在屏幕上看到一句话。的确&#xff0c;我们直接在屏幕上打出这句话会更快。但是编程并不仅限于在屏幕上打出文字这么简单的工作。为了能够进一步写出可…

WCF

http://www.cnblogs.com/wintersun/archive/2011/02/17/1956832.html

C++基础知识(三)—— 常量

一个常量&#xff08;constant&#xff09;是一个有固定值的表达式。 字&#xff08;Literals&#xff09; 字是用来在程序源码中表达特定的值。在前面的内容中我们已经用了很多的字来给变量赋予特定的值。例如&#xff1a; a 5;这句代码中5就是一个字常量。 字常量(literal…

Android获取本机号码及运营商

import android.content.Context; import android.telephony.TelephonyManager; import android.util.Log;public class SIMCardInfo {/*** TelephonyManager提供设备上获取通讯服务信息的入口。 应用程序可以使用这个类方法确定的电信服务商和国家 以及某些类型的用户访问信息…

C++基础知识(四)—— 操作符/运算符

前面已经学习了变量和常量&#xff0c;我们可以开始对它们进行操作&#xff0c;这就要用到C的操作符。有些语言&#xff0c;很多操作符都是一些关键字&#xff0c; 比如add, equals等等。C的操作符主要是由符号组成的。这些符号不在字母表中&#xff0c;但是在所有键盘上都可以…

Java中如何克隆集合——ArrayList和HashSet深拷贝

2019独角兽企业重金招聘Python工程师标准>>> 编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List&#xff0c;Set&#xff0c;ArrayList&#xff0c;HashSet或者其他集合实现的方法。需要记住的是&#xff0c;Java集合的拷贝构造函数只提供浅拷贝而不是深拷…

C++基础知识(五)—— 基本输入输出

控制台(console)是电脑的最基本交互接口&#xff0c;通常包括键盘(keyboard)和屏幕(screen)。键盘通常为标准输入设备&#xff0c;而 屏幕为标准输出设备。 在C的iostream函数库中&#xff0c;一个程序的标准输入输出操作依靠两种数据流&#xff1a;cin 给输入使用和cout给输出…

PHP之preg_replace()与ereg_replace()正则匹配比较讲解

<?php//preg_replace()和ereg_replace()函数的使用的比较// -------preg_replace()--------------------------//1.进行字符串的查找的替换 $str "daoyu shi ge hao hai zi 5555"; $pattern "/\s/"; //如果将…

C++ 控制结构和函数(一) —— 控制结构

一个程序的语句往往并不仅限于线性顺序结构。在程序的执行过程中它可能被分成两支执行&#xff0c;可能重复某些语句&#xff0c;也可能根据一些判断结果而执行不同的语句。因此C 提供一些控制结构语句 (control structures) 来实现这些执行顺序。 为了介绍程序的执行顺序&…

如何安装Favicon

如何安装Favicon favicon.ico图像放在根目录下(也可以是其他目录)在页面源文件的<head></head>标签之间插入 <link rel"shortcut icon" href" /favicon.ico" /> 最后形成: <head> ... <link rel"shortcut icon" hre…

C++ 控制结构和函数(二) —— 函数I(Functions I)

通过使用函数(functions)我们可以把我们的程序以更模块化的形式组织起来&#xff0c;从而利用C所能提供的所有结构化编程的潜力。 一个函数(function)是一个可以从程序其它地方调用执行的语句块。以下是它的格式&#xff1a; type name ( argument1, argument2, ...) statement…