十.数据链路层——MAC/ARP

IP和数据链路层之间的关系

引言

在IP一节中,我们说IP层路由(数据转发)的过程,就像我们跳一跳游戏一样,从一个节点,转发到另一个节点
它提供了一种将数据从A主机跨网络发到B主机的能力
什么叫做跨网络???
本质是要经历很多子网或者局域网
图来自小林网络coding
在这里插入图片描述
也就是说节点与节点之间,不要看只是两台主机
更准确的说,它是同一个局域网内两台不同的主机(两两之间各属于一个子网)
假如我们想要将数据从主机B发送到主机C,我们说IP层为我们提供路径选择,即从哪个节点,跳到哪个节点(跨网络)
假如数据出现错误,我们有TCP层保证可靠性
现在还有一个很关键的问题
在同一个局域网内,为什么主机B会向路由器发消息,而不会向其它人发消息呢?
这就是数据链路层解决的问题——在同一个子网内,数据如何发送
所以我们之前说IP层拥有将数据从A主机跨网络发送到B主机的能力其实并不准确,只不过是讨论该层的时候,已经默认包含了下层的能力
IP层与数据链路层两者联合起来,才拥有将数据从A主机跨网络发送到B主机的能力!

数据链路层的定位和作用

我们可以举回上一次旅行的例子来进一步加深理解
假如我们要从广东东莞出发,去新加坡旅行,我们往往不是一步到位,直接坐飞机就可以到达
相反,我们制定了⼀个行程表,先乘坐公交车到深圳,再坐高铁到香港,然后从香港坐飞机到新加坡
公交车票和高铁票都是去往特定的地点的,每张票只能够在某⼀限定区间内移动,此处的「区间内」就如同通信网络中数据链路
在区间内移动相当于数据链路层,实现区间内两个节点传输的功能
为什么要先到深圳,再到香港,最后才到新加坡?
这些节点的选择是谁来决定的?
这就是我们IP层实现的功能,它就相当于我们的行程表
两者相互搭配,才可以实现从一个地方,跨不同区域到达另一个地方的目标!
总结一下,数据链路层的定位:
用于两个设备(同一种数据链路节点)之间进行传递

以太网

那我从东莞到深圳,除了坐车之外,可不可以坐地铁呢?或者你骑自行车都可以!在同一个区域内,一个节点到另外一个节点的方式有很多种
同样的,在同一个局域网内,一台主机到另外一台主机的方式有很多种,可以说是千差万别,这也是为什么数据链路层不可能被整合像我们的TCP/IP层一样,在OS操作系统内部实现
常见实现的局域网通信技术有下面三种:

以太网:
以太网是一种应用最普遍的计算机局域网技术
它不是一种具体的网络, 而是一种技术标准;
既包含了数据链路层的内容, 也包含了一些物理层的内容
例如以太网中的网线必须使用双绞线; 传输速率有10M, 100M, 1000M等

令牌环网:
令牌环网常用于IBM系统中,在这种网络中有一种专门的帧称为“令牌”,在环路上持续地传输来确定一个节点何时可以发送包.

无线LAN/WAN:
无线局域网是有线网络的补充和扩展,现在已经是计算机网络的一个重要组织部分
像我们的手机连wifi,访问路由器,不用接线吧?都是无线进行操作的

但我们说不用担心,虽然数据链路层存在不同的局域网通信技术,但是我们的路由器可以替我们屏蔽底层网络之间的差异,达到无障碍适配
图来自博主2021dragon
在这里插入图片描述
路由器内部就自带对应不同局域网通信技术的驱动程序,假如根据查找对应的路由表,发现目的IP主机不在这个网络而且采用的是不同的通信技术,就会为我们重新进行对应的封装
这也是为什么我们手机明明采用的是无线LAN/WAN通信技术,但是可以将我们对应的数据发送给对应路由器,和其它底层使用以太网的有线设备进行数据交流.
(手机无线给QQ发消息,电脑端QQ可以收到;或者我们手机微信文件共享给台式电脑,在底层其实都是这个原理.)
类似的技术还有:
虚拟地址空间: 屏蔽了内存之间的差别,让所有的进程看到的都是同一块内存,并且这块内存的布局都是一样的。
一切皆文件: 通过文件结构体和函数指针的方案,让我们能够以对待文件的方式对待某些资源

局域网通信原理

MAC地址

有了上面的铺垫后,我们就可以开始讲解局域网通信原理
我们先来看一个小故事

假如今天大家都在教室内上课,老师突然喊了一句,张三,为什么你的作业昨晚没有按时提交?
张三听到后站了起来,回复道:“不对吧,我记得我昨天明明交了啊!”
老师听到后,给出对应的回复:“好的,那我回去再看看.”

上述故事其实就很好阐述了我们局域网通信的基本原理
第一,老师说话,同学们怎么知道老师叫的是谁呢?
答案是名字,并且此时每个人的名字都具有唯一性
第二,老师喊话张三的时候,其他同学听到消息了吗?
答案是听到了,只不过因为叫的不是自己,所以没有进行对应站起来回答问题的操作
类比到我们局域网通信当中来,每一台主机都有着自己的网卡,一张网卡上就对应有一个全球唯一的MAC地址,它就相当于我们每个同学的名字
在linux下,我们同样可以输入ifconfig指令,查看对应的MAC地址
其中ether是以太网的意思,总共48位
在这里插入图片描述
当一台主机在局域网内发消息时,所有人其实都收到消息了,只不过由于匹配自己的MAC地址后,发现它叫的不是自己,直接在数据链路层,将数据报文丢弃了而已

学习MAC报头

了解了MAC地址后,我们便可以看一下以太网的帧格式是如何的
图来自博主2021dragon
在这里插入图片描述

如何解包/交付

同样的,我们了解任何一个报头,都是从如何解包和向上交付说起
可以很直观的看出,以太网报头是一个定长报头,目的地址,源地址,类型,CRC四个字段加起来总共18个字节,直接分割,即可区分报头和有效载荷
那如何向上交付呢?我们知道网络层不一定用的是IP协议
答案是2个字节的帧类型字段
假如此时数据是IP报文,那对应填充为0800
在这里插入图片描述
PS:ARP,RARP都属于数据链路层,而不是网络层
假如此时数据是一个ARP报文,那对应填充0806
在这里插入图片描述
假如此时数据是一个RARP报文,那对应填充8035
在这里插入图片描述

具体过程

了解了MAC报头后,就可以具体细化我们上面讲述过的小故事了
现在在同一个局域网内,有很多台主机相连,包括我们的路由器也在其中
在这里插入图片描述
假如此时我们的主机A想要和主机E通信,则会发送对应的报文
对应的目的MAC地址填上E的,源目的MAC地址填上自己A的MAC地址即可
在这里插入图片描述
然后报文就会被发到网络当中,此时大家都会收到这个报文
不过大家都会对数据帧进行比对,看一下目的MAC地址和自己是不是一样,假如不一样,则网卡会直接舍弃对应的数据;假如一致,才会把对应的报文向上交付
在这里插入图片描述
那有没有办法,即便MAC地址不同,也会继续向上交付报文呢?
答案是有的!网卡中,可以被设置为混杂模式
设置为混杂模式后,主机就不会对报文的目标MAC地址进行认证,直接向上层交付,这也是我们大部分局域网抓包软件的原理
那我们说要对数据进行保护,是在数据链路层保护吗?
不是!而是我们之前提到过的应用层,对数据自己进行加密,这样别人获取到了,也无法对数据进行解读
假如此时主机A想要发送的数据对象不在这个局域网内,那目的端口MAC地址就填路由器的即可

数据碰撞

但是在一个局域网内,更多时候是多台主机相互发消息,但是这几台主机又是共享一个通信信道的,此时就会出现一个问题——数据相互干扰,更为专业一点的名词,我们称作为数据碰撞
在以太局域网中,任何时候,我们只能有一台主机在给另外一台主机发送数据帧,否则就会发送数据碰撞问题
那我们如何解决这个问题呢?
首先要有碰撞检测,也就是检测到数据的确发生了碰撞,出现了错误
所以我们会发现MAC报头里面有一个CRC字段,它就是用来解决这个问题的,A主机发消息,它自己也会收到,假如CRC校验不通过,说明此时数据发生了碰撞,反之,我们认为数据没有发生碰撞
检测到碰撞后,我们要进行碰撞避免
当主机发送出去的数据产生碰撞时,该主机需要等待一段时间后(sleep一下),再进行数据重发,这样就能够尽可能让局域网当中的数据消散
整体原则是什么?
其实就是采取碰一碰,试一试的策略
有人会说,这不会有点随意吗?
第一, 不要小看光速,实际数据碰撞的概率并不会很高
第二,它其实就是一种另类的重传机制而已,不仅仅TCP层有重传,我们的数据链路层也有!
第三,那我们还可以思考一个问题,数据相对越短,数据碰撞越少,还是相对越长,数据碰撞越少呢?
答案毋庸置疑,数据量一旦很长,横跨的时间段就会很大,一旦发生误码,TCP层会对整个数据进行重传,发生碰撞的概率就会进一步提高
因此我们数据量必须限制一定大小,这就是我们MTU的由来,上层交付的有效载荷不能超过1500字节

如何理解数据碰撞

那我们应该如何看待数据碰撞呢?
局域网在同一个时刻,只允许一台主机向另外一台主机发消息
有没有觉得很熟悉?
局域网的本质,在系统看来其实就是一个临界资源,一台台主机就相当于一个个进程,在同一时刻,我们只允许一个进程访问对应的临界资源
但是,我们说两者采取的策略不同,在系统中,我们采取加锁,信号量等方式;但是网络中采取的是直接试探
令牌环网其实就是如此,它存在一个称作令牌的东西,只有拿到令牌的人,才有资格发消息,拿我们之前的故事举例,只有拿到麦克风的人才有资格说话,其他人暂时闭嘴,令牌本质对应的就是我们系统中的互斥锁
所以,我们说系统和网络不分家,思想贯穿一致
还有一点需要说明
局域网中,主机数目越多,碰撞的概率也会相应增多
这也是为什么我们在大学上大课的时候,人一多,数据就比较难发出去,网络比较卡;或者学校操场校运会时也是如此
本质就是由于不断发生数据碰撞,一直在丢包的缘故!
PS:那假如我们要黑掉一个局域网,其中一个方法便是发送大量垃圾数据,增大数据碰撞概率
为了解决这个问题,对应设备便应运而生
我们称之为网桥,或者说交换机
它的作用就是划分碰撞域
假如我A主机和C主机通信,而不和B主机通信,此时就不用把对应的报文发给B,然后再判断后丢弃
交换机会将两者隔开,分成两个区域,相当于交流的双方有了自己的对话空间,从而减少数据碰撞的概率
假如A主机想要直接向路由器发消息,B主机所在区域也不再需要收到A主机报文,交换机会将报文转给路由器
在这里插入图片描述

ARP协议

我们说同一个局域网内,主机A向主机B发消息,在数据链路层会封装MAC帧,这意味着需要知道对方的IP地址
但是我们只知道对方的IP地址,在套接字socket编程的时候,也仅仅是提供对应的IP而已
那么如何根据对方的IP,得到对方的MAC地址,从而封装我们的MAC帧呢?
这就是我们ARP(Address Resolution Protocol,ARP)协议解决的问题.
它不是一个单纯的数据链路层的协议, 而是一个介于数据链路层和网络层之间的协议;
整体的框架如下图所示:
在这里插入图片描述

小故事

我们还是以我们之前的故事作为引入
现在老师同样要在班上点名回答问题,但是学校只发给老师对应学生的学号,而不是姓名
在老师点学生姓名回答问题之前,老师先要在班里大喊一句:“xxxx学号是哪位同学?你叫什么名字?”
对应的同学会站起来,然后回复老师自己的名字,比如说小明
老师知道他叫小明后,以后就能够通过直接叫小明,然后小明就会站起来回答问题了
同样的,学号其实就是我们的IP地址,姓名其实就相当于我们的MAC地址
在同一个局域网内,双方进行局域网通信之前,可以通过ARP协议,从对应的IP获取到对应的MAC地址
然后再进行局域网通信

协议格式

协议的整体格式如下图所示:
在这里插入图片描述

以太网目的地址/源地址

当想要获取对应接收端的MAC地址时,由于不知道对方的MAC地址,所以以太网的目的地址填充为FFFFFF,代表向整个局域网广播,对应以太网源地址填充上自己的MAC地址即可
当接收端给发送端对应的回应时,以太网MAC地址就可以填充上发送端的MAC地址,源地址此时填上自己接收端的MAC地址
这样一来一回,接收端便知道了目标主机的MAC地址
注意到源MAC地址、目的MAC地址在以太网首部和ARP请求中各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的.

帧类型

这在我们之前讲解封装时已经讲过
之前数据是IP报文,那对应填充为0800
但此时是ARP报文,则填充对应的0806
在这里插入图片描述

硬件类型/协议类型

硬件类型指链路层网络类型,1为以太网;
协议类型指要转换的地址类型,0x0800为IP地址;
硬件地址长度对于以太网地址为6字节;
协议地址长度对于和IP地址为4字节;
对于以太网中发送的ARP报文来说,这四个字段通常是固定的

OP字段

op字段为1表示ARP请求
op字段为2表示ARP应答

具体发送过程

了解协议格式后,我们便可以看一下具体发送过程是怎样的
在这里插入图片描述
假如此时我们的主机A依旧想要和主机E通信,不过在具体两者通信之前,还需要获取到对于主机E的MAC地址
于是A主机就会向局域网当中发送一个ARP报文
其中对于目的MAC地址,由于我们不知道,所以填充上对应的FFFFFF即可。代表广播
在这里插入图片描述
于是所有人都会收到对应的ARP报文,并进行对应的目的IP地址匹配,假如是自己,则可以填充对应的ARP报文返回给主机A;如果不是,则直接在ARP层将对应报文抛弃
在这里插入图片描述
返回的时候,就不用广播地址了,而是直接填上对应的MAC地址,毕竟我们收到对应的ARP报文,是已经知道对方的MAC地址的
此时的op也要从1改为2,代表应答报文
在这里插入图片描述
这是两台主机相互交换的情况,但是实际局域网内,是有很多台主机相互交换的
我们说一台主机,在局域网内部,不要有主人翁意识,大家都一样
任何一台主机都有可能向别人发起ARP请求,或者收到别人给你发的ARP请求
这也正是OP选项字段出现的必要性
所以,任何一台主机,在收到一个ARP报文时,优先看OP,再看对应的目的IP地址
假如OP是1,即这是一个请求报文

假如不是请求自己,直接在ARP层丢弃
假如是请求自己,则构建对应的回应ARP报文返回

假如OP是2,即这是一个回复报文

假如不是请求自己,则直接在MAC帧层丢弃,根本不会往上交付给ARP层
假如是请求自己,才会向上交付给对应的ARP层

还有一个细节需要注意,ARP也是报文,所以经常发ARP报文询问对应的MAC地址,这样也同样可能导致数据碰撞
所以,不是每一次都要ARP,可以将IP地址与对应的MAC地址之间的映射,暂时缓存起来
我们可以在linux系统(windows)下,输入arp -a指令查看我们对应自己的IP地址和MAC地址映射
在这里插入图片描述
当然这种映射是有时间限制的,不然我们每次连wifi,路由器都会随机分配一个动态IP地址给我们,我们的IP地址是会发生改变的,此时映射之间就会发生错误
那有IP地址得到对应MAC地址的协议,有没有MAC地址得到IP地址的协议呢?
答案是有的!它就是我们前面提到过的RARP协议(R代表reverse逆转),也被称为逆地址解析协议,由于IP是直接就知道的,所以不难猜想,它的整个过程和我们的ARP协议类似,但是要简单很多.

ARP欺骗

在之前我们的HTTPS协议中,我们曾经提到过中间人盗取我们数据的知识,具体是怎么利用ARP成为中间人呢?
在这里插入图片描述
同样是我们的局域网,此时存在一个主机M,它想成为中间人的方法很简单
我们说有对应的ARP请求,就会给出对应的ARP回复
但是不妨碍没有请求时,也可以给出对应的ARP回复报文
主机M只要给对应的主机A构建假的ARP应答,告诉主机A,我是E主机,对应IP地址是IP E,MAC地址是MAC M
给对应的主机E构建假的ARP应答,告诉主机E,我是A主机,对应IP地址是IP A,MAC地址是MAC M
在这里插入图片描述
那在主机A和主机E数据交流时,它们以为双方都在和对面直接通信,但其实都经过主机M,这种做法在任何子网,公网都是可以存在的,因为IP地址是公开的.
同样的,我们说假如要使一个局域网暂时瘫痪,也可以发送无效的垃圾ARP报文,想要定向攻击一台主机,也可以发送大量错误的ARP应答等等.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows开启远程桌面

搜索并进入【远程桌面设置】 ​​ 开启远程桌面 ​​​ ipconfig​命令查看ip地址,并使用地址在另一台电脑远程登录此电脑 选择其他账户登录,输入用户和密码 ​​ ​​ 成功登录 ​​

AlDente Pro for Mac(电池最大充电限制工具)v1.24激活版

AlDente Pro for Mac是一款运行在MacOS平台上专业的电池最大充电限制工具。通过 AlDente Pro 您可以设置电池的最大充电百分比设置为 20% 至 100%,然后,它将保持在所需的电池百分比,然后再次使用电源适配器进行充电。 …

VM-Import 导入 Debian 12 系统

介绍 之前介绍过使用 VM-Import 导入 Windows 系统到 AWS 环境启动 EC2 实例, 本文将介绍如何导入 Debian 12 系统. 本地虚拟化使用 VMWare Workstation 创建虚拟机安装和准备 Debian 12 系统, 导出 OVA 文件后上传到 S3 存储桶中再使用 AWSCLI 执行 VM-Import 命令实现导入过…

设计模式-抽象工厂(创建型)

创建型-抽象工厂 角色 抽象工厂: 声明创建一个族产品对象的方法,每个方法对应一中产品,抽象工厂可以是接口,也可以是抽象类;具体工厂: 实现抽象工厂接口,复杂创建具体的一族产品;抽…

[移动通讯]【无线感知-P2】[特征,算法,数据集】

前言: 这里面主要参考清华大学的杨峥教授,做一下无线感知的总结. 基本思想: 无线信号不仅可以传输数据,还可以感知环境信号发射机产生的无线电波 经由直射,反射,散射等多条路径传播,在信号接收机形成的多径叠加信号 携带反映环境特征…

Unreal项目修改名字

Unreal项目修改名字 前言修改Unreal Blueprints工程项目名字修改Unreal C工程项目名字 前言 Unreal项目修改名字还是比较麻烦的,针对纯蓝图工程和C工程有一些区别。 修改Unreal Blueprints工程项目名字 修改纯蓝图的Unreal项目还是比较简单的,只要两个…

hcia datacom学习(12):vlan间路由

不同vlan相当于不同网段,如果vlan间没有三层技术,那么它们就无法互相通信。 vlan间路由可以有3种方式: 1.直接使用路由器转发 *路由器本身不需要额外设置,只需配置端口ip作为网关即可。 *路由器不能处理带有vlan标签的数据帧&a…

vulnhub靶机实战_DC-4

下载 靶机下载链接汇总:https://download.vulnhub.com/使用搜索功能,搜索dc类型的靶机即可。本次实战使用的靶机是:DC-4系统:Debian下载链接:https://download.vulnhub.com/dc/DC-4.zip 启动 下载完成后,…

【PL理论】(5) F#:递归类型 | Immutability 特性(F#中值一旦定义就不会改变)

💭 写在前面:本文旨在探讨不可变数据结构在 F# 编程中的应用,特别是如何利用递归记录类型来表示和操作数值表达式。通过定义存储整数的二叉树和数值表达式的类型,我们将展示不可变性如何简化程序的理解和维护。文章将对比 F# 与命…

适合航天航空的国产FTP替代软件

在宇宙探索的旅程中,航空和航天领域总是站在科技的最前沿,对数据传输的要求特别高。随着信息量急剧增加和安全威胁的复杂化,传统的FTP软件已经不能满足这个高端领域的需要了。因此,找到一款适合航空和航天领域的FTP替代软件&#…

spring 解决循环依赖

在 spring 框架中,我们知道它是通过三级缓存来解决循环依赖的,那么它具体是怎么实现的,以及是否必须需要三级缓存才能解决循环依赖,本文来作相关介绍。 具体实现 先来看看它的三级缓存到底是什么,先看如下代码&#…

Nginx网站服务【☆☆☆】

市面上常用Linux的web服务器:apache、Nginx。 apache与nginx的区别? 最核心的区别在于NGINX采用异步非阻塞机制,多个连接可以对应一个进程;apache采用的是同步阻塞多进程/线程模型,一个连接对应一个进程。apache美国…

c++简略实现共享智能指针Shared_Ptr<T>

重点: 1.引用计数在堆上(原本应为原子变量) 2.引用计数增加减少需要加锁保证线程安全。 3.内部实现Release函数用于释放资源 4.未实现,增加自定义删除器可以将Release修改为模板函数,传入可调用参数。对于shared_p…

tomcat服务器之maxHttpHeaderSize

背景:在OA流程表单中,填写了200条数据,一提交,秒报400错误,且请求没有打到后端中(无报错日志),一开始以为是谷歌浏览器的问题,可百度上关于这个错误的解决方案都是清除缓…

docker实战流程:

Docker-compose是docker官方的开源项目,负责实现对docker容器的集群的快速编排(通过yaml文件docker-compose.yml管理写好容器之间的调用关系只需一个命令就能实现容器的通识开启或关闭)。 类比spring容器,spring管理的是bean而do…

vue3+uniapp

1.页面滚动 2.图片懒加载 3.安全区域 4.返回顶部,刷新页面 5.grid布局 place-self: center; 6.模糊效果 7.缩放 8.微信小程序联系客服 9.拨打电话 10.穿透 11.盒子宽度 12.一般文字以及盒子阴影 13.选中文字 14.顶部安全距离 15.onLoad周期函数在setup语法糖执行后…

PVE安装虚拟主机

本文记录PVE安装其他虚拟主机的步骤,以安装win-server为例。裸机安装PVE则不是本文主题。 准备文件 获取Windows系统镜像 win server镜像可以从官网获取普通Windows镜像可从MSDN获取此外,安装Windows系统还需要从PVE下载特殊驱动 获取Windows必要驱动 …

数据库(25)——多表关系介绍

在项目开发中,进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,各个表之间的结构基本上分为三种:一对多,多对多,一对一。 一对多 例如,一个学校可以有…

PromptPerfect:AI Prompt生成与优化专家

PromptPerfect:AI Prompt生成与优化专家 PromptPerfect是一款专业的AI Prompt生成与优化工具,旨在帮助用户解锁和最大化GPT-4、ChatGPT、Midjourney等先进AI模型的潜力。它通过智能生成和精细优化Prompt,帮助用户获得更精确、更相关、更高效…

Aws EC2,kubeadm方式安装kubernetes(k8s)

版本 docker版本:20.10.25 k8s版本(kubeadm,kubelet和kubectl):1.20.10-0 初始化 # 禁用 SELinux sudo setenforce 0 sudo sed -i s/^SELINUXenforcing$/SELINUXpermissive/ /etc/selinux/config# 关闭防火墙 sudo …