【Linux从青铜到王者】数据链路层(mac,arp)以及ip分片

 局域网通信

通过之前的学习,我们了解了应用层,传输层,网络层的协议和作用,这里先做个总结

  • 应用层——http,https协议,也可以自己定义一套,作用是进行数据的处理
  • 传输层——tcp,udp协议。保证数据传输的可靠性,提供了一个可靠的能力
  • 网络层——ip协议。解决了a主机如何在错综复杂的网络世界中找到b主机,发送的报文可能丢失,但是上层tcp提供可靠性,所以tcp/ip协议可以实现a,b主机之间可靠地互发信息

a主机到b主机之间,必然是经过多次的一层一层的局域网转发的,局域网内是如何转发的,这就是数据链路层要解决的事情

局域网通信就如石头丢进湖里激起的波纹,一个主机要向另一台主机发送消息,就要向局域网里所有的主机都发送信息,主机收到后解析ip是否是自己的,是的话就继续向上解析,不是则丢弃

这里就要用到mac协议了,mac地址是48位的,14亿x2^16,足够大,可以实现全球唯一,不像ip地址一样不够使用

ip协议+路由器+nat只解决了确定目标主机的问题,具体一个局域网里是怎么传送的呢?

a主机要在一个局域网里发送给b主机,此时a拿着自己的ip报文,里面有目标主机的ip,但是不知道b的mac地址,只有知道了才能在mac协议中填写b的mac地址,然后向一个局域网内所有主机发送,b收到后解析发现是传给自己的,就继续解包分用了

mac

mac协议=目的mac(6字节)+源mac(6字节)+帧类型(2字节)+有效载荷+CRC(碰撞检测)

mac的有效载荷可以分为三种:ip报文,arp请求/arp应答,rarp请求/rarp应答,通过帧类型判断

  • 0800为ip报文
  • 0806位arp请求/应答
  • 8035位rarp请求/应答

如何将报头和有效载荷进行分离?固定长度

有效载荷如何向上交付?两字节帧类型,判断是交给数据链路层上层的arp还是网络层ip

上面场景中,我们说了a要在局域网中要和b通信,必须要先知道b的mac地址,此时需要arp

arp是处于数据链路层上层一点的,mac是数据链路层下层一点的,所以arp是夹在ip和mac之间的

假设我们通过arp获得了b的mac地址(发起arp请求的时候目的mac填为全f,表示广播)

此时a,b进行通信的时候,就会将帧类型填位0800,表示有效载荷为ip报文,向局域网里每个主机发送,b收到后先取出报头,发现目的ip是macb,且有效载荷为ip报文,此时就会向上交付给ip层处理,不会交给arp了。

这大概就是mac的传输流程,下面我们再来了解一下arp协议

arp

arp夹在网络层和数据链路层之间

下面借用了一下龙哥的文章,自己写出来总感觉不通顺

原文链接:https://blog.csdn.net/chenlong_cxy/article/details/124788397

arp请求,广播报文

arp应答

arp发送请求 

arp报文的请求字段 

  • 硬件类型指链路层的网络类型,1为以太网。
  • 协议类型指要转换的地址类型,0x0800为IP地址。
  • 硬件地址长度对于以太网地址为6字节,因为MAC地址是48位的。
  • 协议地址长度对于IP地址为4字节,因为IP地址是32位的。
  • op字段为1表示ARP请求,op字段为2表示ARP应答。

前四个请求和应答填的都是一样的,根据第五个来区分是arp请求还是arp应答

arp的完整流程(路由器D向B主机发送信息)

根据ip与子网掩码确认和B的网络号一致,在同一局域网中,准备获得B的mac地址,进行通信

路由器D构建arp请求,向同一局域网里的所有主机发送

首先,因为路由器a构建的是ARP请求,因此ARP请求当中的op字段设置为1。

  • ARP请求当中的硬件类型字段设置为1,因为当前使用的是以太网通信。
  • ARP请求当中的协议类型设置为0800,因为路由器是要根据主机B的IP地址来获取主机B的MAC地址。
  • ARP请求当中的硬件地址长度和协议地址长度分别设置为6和4,因为MAC地址的长度是48位,IP地址的长度是32位。
  • ARP请求当中的发送端以太网地址和发送端IP地址,对应就是路由器D的MAC地址和IP地址。
  • ARP请求当中的目的以太网地址和目的IP地址,对应就是主机B的MAC地址和IP地址,但由于路由器D不知道主机B的MAC地址,因此将目的以太网地址的二进制序列设置为全1,表示在局域网中进行广播

ARP请求构建完成后,为了能将ARP请求发送到以太网当中,还需要将ARP数据包向下交付给MAC帧协议,封装成MAC帧

  • 封装MAC帧报头时,以太网目的地址和以太网源地址,对应分别是主机B和路由器D的MAC地址,但由于路由器D不知道主机B的MAC地址,因此MAC帧报头当中的以太网目的地址的二进制序列也只能设置为全1,表示在局域网中进行广播。
  • 因为这里封装的是一个ARP请求数据包,因此MAC帧当中的帧类型字段设置为0806。
  • 由于ARP请求数据包的长度只有28字节,不足46字节,因此还需要在MAC帧的有效载荷当中补上18字节的填充字段,最后再对MAC帧进行CRC校验即可。

  • 此时该局域网中的所有主机都收到该mac帧,发现目的ip为全f,且帧类型为0806,为arp请求或应答,则交给arp
  • 当ARP层收到这个数据包后,发现ARP数据包当中的op字段为1,于是判定这是一个ARP请求,然后再提取出ARP数据包当中的目的IP地址字段,虽然局域网当中的所有主机都会将该数据包交给自己的ARP层,但最终只有主机B发现ARP数据包当中的目的IP地址与自己相同,因此只有主机B会对该ARP请求进行应答,而局域网当中的其他主机在识别到ARP数据包当中的目的IP地址与自己不匹配后,就会直接将这个ARP请求报文丢弃。

需要注意的是,局域网当中其他不相干的主机在收到这个ARP请求报文后,不是在MAC帧层丢弃的,而是在ARP层发现该ARP数据包的目的IP与自己的IP不匹配后丢弃的。

总结:

发起方构建ARP请求,以广播的方式发送给每一个主机。
每台主机都能识别接收,然后根据MAC帧的帧类型字段将有效载荷交付给每个主机的ARP层。
其他不相关主机立马根据目的IP,在自己的ARP协议内部丢弃ARP请求,只有目标主机会处理请求

arp发送应答

主机B在应答时首先需要构建ARP应答。

  • 首先,因为主机B构建的是ARP应答,因此ARP协议当中的op字段设置为2。
  • ARP应答当中的硬件类型、协议类型、硬件地址长度、协议地址长度的值与ARP请求当中设置的值相同。
  • ARP应答当中的发送端以太网地址和发送端IP地址,对应就是主机B的MAC地址和IP地址。
  • ARP应答当中的目的以太网地址和目的IP地址,对应就是路由器D的MAC地址和IP地址,因为路由

此时ARP请求就被封装成MAC帧了,如下:

  • 此时局域网当中的每台主机在底层都能收到这个MAC帧,但局域网当中的不相干的主机,在发现该MAC帧对应的以太网目的地址与自己不同后,就会将该MAC帧丢弃,而不会交付给上层ARP层,最终只有路由器D会将解包后MAC帧的有效载荷向上交付给自己的ARP层。
  • 当路由器D的ARP层收到这个数据包后,发现ARP数据包当中的op字段为2,于是判定这是一个ARP应答,然后就会提取出ARP数据包当中的发送端以太网的地址和发送端IP地址,此时路由器D就拿到了主机B的MAC地址。

至此,路由器D知道了B的mac地址,就可以进行局域网通信了

arp缓存表

如果每次通信前都要进行arp请求应答那也太麻烦,所以在第一次arp请求的时候,会将对应的信息进行保存一段时间,第二次发送信息就可以直接发送了

结论:

  • 主机得到arp应答,会将arp应答缓存起来(有时间限制),如果收到许多同类型的,会将最新的缓存起来
  • 任何一台主机,都可能即会收到arp应答,又会收到arp请求

碰撞问题

因为局域网中任何一个主机要发消息,所有主机都要收到,如果这个时候又有另一台一起发,就会产生碰撞

所以局域网中,任何时候只允许一台主机发送数据,如果同时发送会产生数据碰撞的问题

mac帧最后的crc用来检测是否发生碰撞,如果发生则执行碰撞避免算法,简单理解就是发生碰撞的主机等待一段时间后再发

数据分片

tcp中我们讲到将缓冲区理解成一个一个的环形字节数组,是因为数据链路层的原因

受限于物理底层各种因素,如果要传送的数据太大,是会分片的,也就是将一个大的数据分成几个小的数据来发送

ip协议第二行字段就是用来分片用的

上面根据mac帧报文我们知道,MAC帧携带的有效载荷的最大长度是有限制的,也就是说IP交给MAC帧的报文不能超过某个值,这个值就叫做最大传输单元(Maximum Transmission Unit,MTU),这个值的大小一般是1500字节。

由于MAC帧无法发送大于1500字节的数据,因此IP层向下交付的数据的长度不能超过1500字节,这里所说的数据包括IP的报头和IP的有效载荷

如果IP层要传送的数据超过了1500字节,那么就需要先在IP层对该数据进行分片,然后再将分片后的数据交给下层MAC帧进行发送

如果发送数据时在IP层进行了分片,那么当这些分片数据到达对端主机的IP层后就需要先进行组装,然后再将组装好的数据交付给上层传输层。

 

 分片一定是不好的,提高了数据的发送个数,增加了丢包概率

如何做到不分片呢?将每次发送的数据限制在规定大小内,这也是之前为什么tcp发送缓冲区画成一小格一小格的原因

分片和组装都是在ip层完成的,传输层和数据链路层不需要关心

  • 传输层只负责为数据传送提供可靠性保证,比如当数据传送失败后,传输层的TCP协议可以组织进行数据重传。
  • 当TCP将待发送的数据交给IP后,TCP并不关心该数据是否会在IP层进行分片,即TCP并不关心数据具体的发送过程。
  • 当TCP从IP获取到数据后,TCP也不关心该数据是否在IP层经过了组装。

而链路层的MAC帧只负责,将数据从一个节点传送到和自己相连的下一个节点。

  • 当IP将待发送的数据交给MAC帧后,MAC帧并不知道该数据是IP经过分片后的某个分片数据,还是一个没有经过分片的数据,MAC帧只知道它一次最多只能发送MTU大小的数据,如果IP交给MAC帧大于MTU字节的数据,那MAC帧就无法进行发送。
  • 当MAC帧从网络中获取到数据后,MAC帧也不关心这个数据是否需要进行组装,MAC帧只需要将该数据的MAC帧报头去掉后直接上交给上层IP就行了,而至于该数据的组装问题则是IP需要解决的。

因此,数据的分片和组装完全是由IP协议自己完成的,传输层和链路层不必关心也不需要关心。

分片的过程

ip的第二行字段

  • 16位标识:唯一标识主机发送的报文,如果数据在IP层进行了分片,那么每一个分片报文的16位标识是相同的。
  • 3位标志:第一位保留,表示暂时没有规定该字段的意义。第二位表示禁止分片,表示如果报文长度超过MTU,IP模块就会丢弃该报文。第三位表示“更多分片”,如果报文没有进行分片,则该字段设置为0,如果报文进行了分片,则除了最后一个分片报文设置为0以外,其余分片报文均设置为1。
  • 13位片偏移:分片相对于原始数据开始处的偏移,表示当前分片在原数据中的偏移位置,实际偏移的字节数是这个值× 8 \times 8×8得到的。因此除了最后一个报文之外,其他报文的长度必须是8的整数倍,否则报文就不连续了

假设IP层要发送4500字节的数据,由于超过MTU,IP需要先将该数据进行分片,然后再将一个个的分片交给MAC帧进行发送

分片报文总字节数IP报头字节数数据字节数16位标识“更多分片”13位片偏移
1150020148012310
215002014801231185
315002014801231370
48020601230555

 

分片的组装

MAC帧交给iP层的数据可能来自世界各地,这些数据可能是经过分片后发送的,也可能是没有经过分片直接发送的,因此IP必须要通过某种方式来区分收到的各个数据。

  • IP报头当中有32位源IP地址,源IP地址记录了发送端所对应的IP地址,因此通过IP报头当中的32位源IP地址就可以区分来自不同主机的数据。
  • IP报头当中有16位标识,未分片的数据各自的16位标识都是不同的,而由同一个数据分片得到的各个分片报文所对应的16位标识都是相同的,因此通过IP报头当中16位标识就可以判断哪些报文是没有经过分片的独立报文,哪些报文是经过分片后的分片报文。
  • 因此IP可以通过IP报头当中的32位源IP地址和16位标识,将经过分片的数据各自聚合在一起,聚合在一起后就可以开始进行组装了。

对于各个分片报文来说:

  • 第一个分片报文中的13位片偏移的值一定为0。
  • 最后一个分片报文中的“更多分片”标志位一定为0。
  • 对于每一个分片报文来说,当前报文的13位片偏移加上当前报文的数据字节数 ÷ \div÷ 8所得到的值,就是下一个分片报文的所对应的13位片偏移。
  • 根据分片报文的这三个特点就能够将分片报文合理的组装起来。

先找到分片报文中13位片偏移为0的分片报文,然后提取出其IP报头当中的16位总长度字段,通过计算即可得出下一个分片报文所对应的13位片偏移,按照此方式依次将各个分片报文拼接起来。
直到拼接到一个“更多分片”标志位为0的分片报文,此时表明分片报文组装完毕。

分片报文丢包的问题

片后的报文在网络传输过程中也可能会出现丢包问题,但接收端有能力判断是否收到了全部分片报文,比如假设某组分片报文对应的16位标识值为x:

  • 如果分片报文中的第一个分片报文丢包了,那么接收端收到的分片报文中就找不到对应16位标识为x,并且13位片偏移为0的分片报文。
  • 如果分片报文中的最后一个分片报文丢包了,那么接收端收到的分片报文中就找不到对应16为标识为x,并且“更多分片”标志位为0的分片报文。
  • 如果分片报文中的其它分片报文丢包了,那么接收端在进行分片报文的组装时就会找不到对应13位片偏移为特定值的分片报文。
  • 需要注意的是,未分片报文的“更多分片”标志位为0,最后一个分片报文的“更多分片”标志位也为0,但当接收端只收到分片报文中的最后一个分片报文时,接收端不会将其识别成一个未分片的报文,因为未分片的报文所对应的13位片偏移的值也应该是0,而最后一个分片报文所对应的13位片偏移的值不为0。

因此只有当一个报文的13位片偏移为0,并且该报文的“更多分片”标志位也为0时,该报文才会被识别成一个没有被分片的独立报文,否则该报文就会被识别成一个分片报文。
 

 

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

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

相关文章

Linux絮絮叨(三) Ubuntu桌面版添加中文拼音输入法

步骤很详细,直接上教程 一. 配置安装简体拼音输入法 #安装相应的平台支持包 sudo apt install ibus-gtk ibus-gtk3# 安装简体拼音输入法 sudo apt install ibus-pinyin安装完成如果下面的步骤找不到对应输入法可以重启一下,一般不需要 二. 添加简体拼音…

Springboot 2.7+解决跨域问题,到底是在SpringBoot中添加拦截器还是修改Nginx配置

文章目录 1摘要2 核心代码2.1 SpringBoot 全局跨域拦截器2.2 Nginx 配置跨域处理2.3 Nginx 和 SpringBoot 同时添加允许跨域处理会怎么样? 3 推荐参考资料 1摘要 跨域问题报错信息: Referrer Policy:strict-origin-when-cross-origin跨域问题是在前后端分离的情况…

Ubuntu Server 22.04.5 LTS重启后IP被重置问题

Ubuntu Server 22.04.5 LTS重启后IP被重置问题 最近在使用Ubuntu Server 22.04做项目开发测试时发现每次重启和关机后,所设置的静态IP地址都会回复到安装系统时所设置的ip Ubuntu Server 22.04 官网下载地址:Ubuntu官方下载地址 对虚拟机下安装Ubuntu感…

052-linux安装MySQL数据库-保姆级

linux安装MySQL数据库 1.mysql数据库安装1.1.安装环境1.2.安装部署 2.mysql数据库主备实现2.1.主备配置2.1.1.前置环境准备2.1.2.master数据库服务器配置2.1.3.slave数据库服务器配置 2.2.主备故障切换 3.mysql数据库主主实现 1.mysql数据库安装 1.1.安装环境 操作系统版本&a…

棋牌游戏项目ctrl + c无法退出进程问题

棋牌游戏项目ctrl c无法退出进程问题 运行的服务为 user , 启动命令为 cd user && go run main.go启动之前先加入调试语句 在 go func() { metric.Serve(...) } 打日志在 app.Run(...) 打日志 user/main.go var configFile flag.String("config", "…

GAMES101 完结篇(笔记和作业)

写在前面 我已经把笔记和作业代码放在了GitHub上,欢迎访问GAMES101笔记及作业 (github.com),如果对你有帮助,欢迎fork or star 下面我想简单介绍一下这里面的东西 Homework Homework文件夹里有0~8的作业框架,参考的其他大佬的代…

uniapp 添加loading

在uniapp中添加loading可以使用uni的API uni.showLoading 方法。以下是一个简单的示例代码 // 显示loading uni.showLoading({title: 加载中 });// 假设这里是异步操作,比如网络请求 setTimeout(function () {// 隐藏loadinguni.hideLoading(); }, 2000);

持续迭代,做一个可以投入项目真正使用的业务容器及插件

问题 上一篇文章中已经可以允许插件中有自己的依赖jar包了(原理就是插件中依赖jar包交给插件专属的插件类加载器PluginClassLoader进行加载,业务系统中依赖的jar包交由业务类加载器AliooClassLoader进行加载) 大家知道java中是尽可能面向对象…

PostgreSQL数据delete删除恢复

第一部分 文档描述 本文档适用数据表数据被delete类型的删除语句情况下恢复,需要满足数据库或数据表未被vacuum或者vacuum full 第二部分 操作步骤 2.1 创建测试表 创建测试表novels,并插入测试数据 dbtest# create table novels (name varchar(200)…

多线程(二)- Java内置锁的核心原理

前言 Java内置锁是一个互斥锁,这就意味着最多只有一个线程能够获得该锁,当线程B尝试去获得线程A持有的内置锁时,线程B必须等待或者阻塞,直到线程A释放这个锁,如果线程A不释放这个锁,那么线程B将永远等待下…

2024年12月7日Github流行趋势

项目名称:lobe-chat 项目维护者:arvinxx, semantic-release-bot, canisminor1990, lobehubbot, renovate项目介绍:Lobe Chat 是一个开源的现代化设计的人工智能聊天框架。支持多AI提供商(OpenAI / Claude 3 / Gemini / Ollama / Q…

群控系统服务端开发模式-应用开发-邮件工厂QQ发送开发

一、邮件发送类实例修改 在Mail目录下修改邮件发送类实例&#xff0c;具体代码如下&#xff1a; <?php /*** 创建邮件发送类实例工厂* User: 龙哥三年风水* Date: 2024/12/5* Time: 14:32*/ namespace Mail; use app\model\param\Emailsms; use Error\BaseError; use Mail…

Golang内存模型总结1(mspan、mcache、mcentral、mheap)

1.内存模型 1.1 操作系统存储模型 从上到下分别是寄存器、高速缓存、内存、磁盘&#xff0c;其中越往上速度越快&#xff0c;空间越小&#xff0c;价格越高。 关键词是多级模型和动态切换 1.2 虚拟内存与物理内存 虚拟内存是一种内存管理技术&#xff0c;允许计算机使用比…

ASP.NET Core8.0学习笔记(二十五)——EF Core Include导航数据加载之预加载与过滤

一、导航属性数据加载 1.在EF Core中可以使用导航属性来加载相关实体。 2.加载实体的三种方式&#xff1a; (1)预先加载&#xff1a;直接在查询主体时就把对应的依赖实体查出来&#xff08;作为初始查询的一部分&#xff09; (2)显式加载&#xff1a;使用代码指示稍后显式的从…

MATLAB Simulink® - 智能分拣系统

系列文章目录 前言 本示例展示了如何在虚幻引擎 环境中对四种不同形状的标准 PVC 管件实施半结构化智能分拣。本示例使用 Universal Robots UR5e cobot 执行垃圾箱拣选任务&#xff0c;从而成功检测并分类物体。cobot 的末端执行器是一个吸力抓手&#xff0c;它使 cobot 能够拾…

环形链表 (简单易懂)

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;…

【C++】奇偶数判断题的高级分析与优化

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;1. 题目描述题目背景 &#x1f4af;2. 基本解决思路示例分析 &#x1f4af;3. 原始代码分析代码分析代码优点代码缺点 &#x1f4af;4. 教师代码及其优化分析代码分析代码优…

1.1 Beginner Level学习之“创建 ROS msg 和 srv”(第十节)

学习大纲&#xff1a; 1. msg 和 srv msg 文件是描述 ROS 消息字段的简单文本文件。它们用于为不同语言生成消息的源代码。srv 文件则描述了一个服务&#xff0c;包括两部分&#xff1a;请求和响应。Srv 文件用于生成服务的源代码。msg 文件存储在包的 msg 目录中。srv 文件存…

Linux-笔记---系统文件I/O

1. open函数和close函数 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);#include <unistd.h> int close(int fd); open函数…

红日靶场vulnstark 4靶机的测试报告[细节](一)

目录 一、测试环境 1、系统环境 2、注意事项 3、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、漏洞利用Getshell ①Struts 2 s2-045漏洞 手工利用s2-45漏洞 Msf综合利用 ②Tomcat框架(CVE-2017-12615) ③phpMyAdmin(CVE-2018-12613) 构造语句写入冰蝎木…