十.数据链路层——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应答等等.

相关推荐
Lightning-py43 分钟前
Linux命令cat /proc/net/snmp查看网络协议层面统计信息
网络·网络协议·tcp/ip
wo3258661451 小时前
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
开发语言·网络·php
獨枭2 小时前
配置 macOS 上的 Ruby 开发环境
开发语言·macos·ruby
光路科技2 小时前
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
服务器·网络·重构
云盾安全防护4 小时前
CC攻击与WAF的对抗战
网络·安全·ddos
还是鼠鼠5 小时前
HTTP 请求协议简单介绍
java·开发语言·网络·网络协议·http
网硕互联的小客服6 小时前
如何在服务器上部署 Python Django 应用
linux·运维·服务器·网络·安全
库奇噜啦呼7 小时前
push [特殊字符] present
macos·ios·cocoa
安和昂8 小时前
【iOS】多线程NSOperation,NSOperationQueue
macos·ios·cocoa
咕噜签名分发冰淇淋8 小时前
Flutter 打包 iOS 苹果 IPA 应用有哪些优势?如何实现?
macos·objective-c·cocoa