Linux 50 IP协议深度解析:从报头结构到子网划分与NAT

🔥个人主页: Milestone-里程碑

❄️个人专栏: <<力扣hot100>> <<C++>><<Linux>>

🌟心向往之行必能至

目录

一.IP协议

[1.1 IP协议的核心作用和构成](#1.1 IP协议的核心作用和构成)

[1.2 ip协议的报头](#1.2 ip协议的报头)

[1.3 网络划分(重点)](#1.3 网络划分(重点))

[1.3.1 为什么要子网划分](#1.3.1 为什么要子网划分)

[1.3.2 设置IP](#1.3.2 设置IP)

[1.3.2.1 解决IP不足](#1.3.2.1 解决IP不足)

[1.3.2.2 特殊的IP地址](#1.3.2.2 特殊的IP地址)

[1.4 IP地址的数量限制](#1.4 IP地址的数量限制)

1.4.1解决办法:私有IP和公有IP

[1.4.1.1 引入例子,加强理解](#1.4.1.1 引入例子,加强理解)

[1.4.1.2 再引入例子,更加详细,从市的局域网与公网](#1.4.1.2 再引入例子,更加详细,从市的局域网与公网)

1.4.1.3网络拓扑

[1.4.1.4 查看主机配置的IP](#1.4.1.4 查看主机配置的IP)

[1.5 报文分片](#1.5 报文分片)

[1.5.1 学习分片和组装](#1.5.1 学习分片和组装)

[1.5.2 细讲补充](#1.5.2 细讲补充)


一.IP协议

基本概念
主机: 配有IP地址, 也要进⾏路由控制的设备;
路由器: 即配有IP地址, ⼜能进⾏路由控制;(工作在网络层,但现在的路由器,应用层也可工作)
节点: 主机和路由器的统称

1.1 IP协议的核心作用和构成

IP协议:提供一种能力看,将数据报从A主机,跨网络,送到B主机

理解网络层和传输层

在数据传输过程中,网络层的IP有能力将数据传输成功

但有能力不代表一定能,此时就需要与传输层的TCP合作

这样,TCP/IP协议,才能把数据百分百可靠的,从A主机跨网络送到B主机

1.2 ip协议的报头

首先,我们要明确,IP协议的报头为固定长度,20字节,但这里4位头部长度,也才15啊,其实与TCP一样,基本单位是4个字节

0,15\]-\>4字节 \[0,60\] 然后 20/4-\>5-\>4+1-\>0100+0001-\>0101 ![](https://i-blog.csdnimg.cn/direct/d9b933dab30946b99a13ea566777a6ef.png) > 8位服务类型 > 8位服务类型(Type Of Service): 3位优先权字段(已经弃⽤), 4位TOS字段, 和1位保留字段(必须置 为0). 4位TOS分别表⽰: 最⼩延时, 最⼤吞吐量, 最⾼可靠性, 最⼩成本. 这四者相互冲突, 只能选择 ⼀个. 对于ssh/telnet这样的应⽤程序, 最⼩延时⽐较重要; 对于ftp这样的程序, 最⼤吞吐量⽐较重要. > 8位⽣存时间( > Time To Live, TTL): 数据报到达⽬的地的最⼤报⽂跳数. ⼀般是64. 每次经过⼀个路 > 由, TTL -= 1, ⼀直减到0还没到达, 那么就丢弃了. 这个字段主要是⽤来防⽌出现路由循环 > 如: > 有时会出现报条一直在内部循环转发 > ![](https://i-blog.csdnimg.cn/direct/a3fe288d6e5c43c6ad6c324cd6636c16.png) > 16位首部检验和,使⽤CRC进⾏校验, 来鉴别头部是否损坏 > > 与TCP所讲一样,是防止比特位翻转的 struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined(__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #error "Please fix " #endif __u8 tos; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ }; > 4位版本号(version): > 指定IP协议的版本, 对于IPv4来说, 就是4 > • 8位协议: 表⽰上层协议的类型 > • 32位源地址和32位⽬标地址: 表⽰发送端和接收端. > 16位总⻓度(total length): IP数据报整体占多少个字节. > 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4 剩余的报头组成,在后续详细讲解 ### 1.3 网络划分(重点) IP地址分为两个部分, ⽹络号和主机号 • ⽹络号: 保证相互连接的两个⽹段具有不同的标识; • 主机号: 同⼀⽹段内, 主机之间具有相同的⽹络号, 但是必须有不同的主机号 *** ** * ** *** 先建立共识,为什么我们发消息能够精准发送,本质上是网络本身是发展几十年的产物,与此同时,网络建设也是发展了几十年的(国内运营商建立基站,拉网线等)---网站是被设计的 引入例子加强理解,一所大学里,假设都分好了学院,而我们假设学号是:院号+专业+班级+学号 就如我们下面这张图,其中学院内的学生,除了该学院的学生会主席与其他院的学生会主席建立了校群,有向外通信的能力,其他的学生,都只能在自己这个院的局域网通信(此处我们简化了,其实应该还要班级等等联络人) ![](https://i-blog.csdnimg.cn/direct/17dabef2ffe34c73b04bb3813137b684.png) 假设某天下雨,学号为01123的张三捡到了一个钱包,里面有许多贵重物品和一张学生卡(由于雨水,只能看到学号:03333) 而张三为了将这个钱包物归原主,可以在大学里一个一个地找,但效率太低,因此就应该通信 张三看学院号为03333,非自己学院号的01,自己不认识,不会通信,此时就采用了缺省值,交给院学生会主席01110,同时带上源IP地址(学号:01123)和目的IP地址(03333),而主席看到后,发现是材料学院的,就将这个转发1给材料学院的学生会主席,材料学院的学生会主席看到后,将带有目的IP和源IP和数据:钱包就交给了目的IP的人 *** ** * ** *** 与我们说过网络是被建设的,同样的,在我们没有上大学的时候,上面的学院也有了---\>被学校已经建设好了(划分学院,带上唯一编号的过程:子网划分) #### 1.3.1 为什么要子网划分 未来查找目标主机,必须先查找目标网络 本质: > 本质是淘汰其他网络,可以在全网中提高查找目标主机的效率 > > 在上面的学校例子中,张三淘汰了自己学院的学生,院学生会主席淘汰了除材料学院的学生,材料的学生会主席淘汰了院内除目的学生的学生 > 同时,二分查找也是通过不断淘汰,提高效率 *** ** * ** *** • 不同的⼦⽹其实就是把⽹络号相同的主机放到⼀起. • 如果在⼦⽹中新增⼀台主机, 则这台主机的⽹络号和这个⼦⽹的⽹络号⼀致, 但是主机号必须不能 和⼦⽹中的其他主机重复. 如下面的主机A/B/C等都有网络标识,那么哪里来的呢? 其实是我们连网时,向路由器请求,路由器自动分配(DHCP)(断网可能会回收) ![](https://i-blog.csdnimg.cn/direct/8a113d02fb7c4c218c5773858a4ecfe6.png) 而我们的路由器,既要与内部设备通信,又要与外部通信,因此至少需要配置有两套IP #### 1.3.2 设置IP IP是有限的,被各个国家的运营商抢占 为何要抢?构建自己的子网 ⼿动管理⼦⽹内的IP, 是⼀个相当⿇烦的事情. • 有⼀种技术叫做DHCP, 能够⾃动的给⼦⽹内新增主机节点分配IP地址, 避免了⼿动管理IP的不便. • ⼀般的路由器都带有DHCP功能. 因此路由器也可以看做⼀个DHCP服务器. > IP=网络号+主机号 > 子网划分的本质:把32位比特位进行划分,确定有多少网络号 *** ** * ** *** 过去曾经提出⼀种划分⽹络号和主机号的⽅案, 把所有IP 地址分为五类(IPV4) ![](https://i-blog.csdnimg.cn/direct/c014fffb008e49de9cddedfe8b2f0df7.png) > • A类 0.0.0.0到127.255.255.255 > • B类 128.0.0.0到191.255.255.255 > • C类 192.0.0.0到223.255.255.255 > • D类 224.0.0.0到239.255.255.255 > • E类 240.0.0.0到247.255.255.255 但 > 随着Internet的⻜速发展,这种划分⽅案的局限性很快显现出来,⼤多数组织都申请B类⽹络地址, 导致B 类地址很快就分配完了, ⽽A类却浪费了⼤量地址; > • 例如, 申请了⼀个B类地址, 理论上⼀个⼦⽹内能允许6万5千多个主机. A类地址的⼦⽹内的主机数 更多. > • 然⽽实际⽹络架设中, 不会存在⼀个⼦⽹内有这么多的情况. 因此⼤量的IP地址都被浪费掉了 ##### 1.3.2.1 解决IP不足 针对这种情况提出了新的划分⽅案, 称为CIDR(Classless Interdomain Routing)(⽆类别域间路由): • 引⼊⼀个额外的⼦⽹掩码(subnet mask)来区分⽹络号和主机号; • ⼦⽹掩码也是⼀个32位的正整数. 通常⽤⼀串 "0" 来结尾; • 将IP地址和⼦⽹掩码进⾏ "按位与" 操作, 得到的结果就是⽹络号; • ⽹络号和主机号的划分与这个IP地址是A类、B类还是C类⽆关; *** ** * ** *** 举两个例子 子网掩码,即将IP与子网掩码进行\& ![](https://i-blog.csdnimg.cn/direct/b581284c8c244390821364dad9877604.png) 通过子网掩码 的设置,原来68这部分的0100 0000+ 0100 = 0100 0100全变为了0![](https://i-blog.csdnimg.cn/direct/52e8486f7f464cb2a2b6f16788fd862c.png) 因此,子网存在的意义就是通过设置1的个数,重新设计网络号,使IP资源得到充分利用 上面这个 140.252.20.68/24后,子网地址范围,即这个子网最多连多少台主机 为256-1(子网后的为全0,表示局域网)-1(子网后全为1,表示广播地址(后续讲)) > 如果觉得上面的划分还是有点浪费,那么可以尝试下面的 ![](https://i-blog.csdnimg.cn/direct/77961306f8534807be8f14138580119b.png) 上面的这个子网最多连14台主机 ##### 1.3.2.2 特殊的IP地址 • 将IP地址中的主机地址全部设为0, 就成为了⽹络号, 代表这个局域⽹; • 将IP地址中的主机地址全部设为1, 就成为了⼴播地址, ⽤于给同⼀个链路中相互连接的所有主机发 送数据包; • 1 27.\*的IP地址⽤于本机环回(loop back)测试,通常是127.0.0.1 ### 1.4 IP地址的数量限制 我们知道, IP地址(IPv4)是⼀个4字节32位的正整数. 那么⼀共只有 2的32次⽅ 个IP地址, ⼤概是43亿左 右. ⽽TCP/IP协议规定, 每个主机都需要有⼀个IP地址. 这意味着, ⼀共只有43亿台主机能接⼊⽹络么? 实际上, 由于⼀些特殊的IP地址的存在, 数量远不⾜43亿; 另外IP地址并⾮是按照主机台数来配置的, ⽽ 是每⼀个⽹卡都需要配置⼀个或多个IP地址. CIDR在⼀定程度上缓解了IP地址不够⽤的问题(提⾼了利⽤率, 减少了浪费, 但是IP地址的绝对上限并没 有增加), 仍然不是很够⽤. 这时候有三种⽅式来解决: > • 动态分配IP地址: 只给接⼊⽹络的设备分配IP地址. 因此同⼀个MAC地址的设备, 每次接⼊互联⽹ > 中, 得到的IP地址不⼀定是相同的; > • NAT技术(后⾯会重点介绍); > • IPv6: IPv6并不是IPv4的简单升级版. 这是互不相⼲的两个协议, 彼此并不兼容; IPv6⽤16字节128 > 位来表⽰⼀个IP地址; 但是⽬前IPv6还没有普及; ##### 1.4.1解决办法:私有IP和公有IP 如果⼀个组织内部组建局域⽹,IP地址只⽤于局域⽹内的通信,⽽不直接连到Internet上,理论上 使⽤任意 的IP地址都可以,但是RFC 1918规定了⽤于组建局域⽹的私有IP地址 > • **10.**\*,前8位是⽹络号,共16,777,216个地址 > • **172.16.\***到172.31.\*,前12位是⽹络号,共1,048,576个地址 > • **192.168.\***,前16位是⽹络号,共65,536个地址 > 包含在这个范围中的, 都成为私有IP, 其余的则称为全局IP(或公⽹IP); > 网络宏观上被划分为: > > 公网:内网(子网,局域网)=1:n > > 但需要注意的是,我们普通人接入的都是内网,并且在网络通信的过程中,私有IP不可以出现在公网 *** ** * ** *** ###### 1.4.1.1 引入例子,加强理解 ![](https://i-blog.csdnimg.cn/direct/78b685d088884be49b18d28296c203e8.png) 假设上面刚开始发的 ![](https://i-blog.csdnimg.cn/direct/6cf49ede96294ce5ba80d42b98515990.png) 而发送主机发现122.开头的不在自己的局域网内,无法直接通信,于是就缺省路由,将它 转发给路由器,而路由器发现dst也不是自己所在的局域网,所以再缺省路由,发给他对应的路由器,同时通过NAT,将src地址匾额我i自己的QAN口IP ![](https://i-blog.csdnimg.cn/direct/1fb2f27c11b549f7ba3f2e7e9548beb6.png) 而接受到的路由器,发现122.\*与自己处在同一个网络内,可以直接通信,因此直接进行发送,并将src替换为自己的WAIN口 ![](https://i-blog.csdnimg.cn/direct/4338a124c4d64a5fa89286cd1ad8291c.png) 目的路由器接受到后,再根据后续的主机地址发送给目的地,处理完再返回,而由于有公网的src IP,所以一定能返回路径的倒数第一个经过点,但返回到后,src与自己的WAIN口ip一样了,无法进行访问了,怎么办? > 其实与前面使用NAT替换一样,会进行处理,此处后面详解 *** ** * ** *** 上面的过程中,我们发现堆src ip要一步一步进行替换,最多会替换到公网IP再完成任务后反向替换 试问: 如果 私有IP可以出现在公网上,那么我们局部的通信设备访问公网资源可以访问,但给我们返回应答时,该怎么处理? (私有IP只在子网为1,但如果我们不同的子网,相同的私有ip直接出现在公网,返回就不知返回给谁了) **欠费,敏感信息** 如果我们绑定路由器的手机号欠费了,我们会发现自己无法使用wifi了,其实是我们发送的报文里,携带了话费余额,运营商看到欠费后,就不帮我们转发了 我们访问国外网站或者其他敏感信息的时候,会发现无法访问, 其实就是运营商检测到有敏感信息,不帮我们转发 公网的理解 每个国家都有公网IP进行组建自己的内网,而公网IP的多少,则是看网民的数量 *** ** * ** *** 小总结 > 1.上面通过NAT技术及私有IP不可出现在公网,就解决了IP地址不足的问题 > > 2.每经过一个内网路由器,进行srcip的时候,替换成为当前路由器的wan口ip,(对外的) > > 3.上面的例子,我们也可以感受到,每个路由器,至少要配套两个IP ###### 1.4.1.2 再引入例子,更加详细,从市的局域网与公网 ![](https://i-blog.csdnimg.cn/direct/f7955ba842ad4cc79f7f84281d723dfb.png) ![](https://i-blog.csdnimg.cn/direct/5b8c0f74574847f38f18bf23656c6e82.png) 一,国外俄罗斯的地址访问5.1.16.X,发给中国,一层一层替换src 而对应那些大公司,我们就可以将它们想像与市的服务器同级,而大厂的服务器一般在多个区域都会有部署 *** ** * ** *** ###### 1.4.1.3网络拓扑 网络拓扑的结构非常复杂,这里我们把上面的"市",替换成为各个互联网公司,那么内网环境就是公司内网 ###### 1.4.1.4 查看主机配置的IP linux : route ![](https://i-blog.csdnimg.cn/direct/a5de8dace68b40689faa1920b5ee3c1f.png) 此时我们看到的default对应的ip就是缺省ip,当源地址要访问的ip在路由器未配置时,就转发给该ip 下面是两个例子 ![](https://i-blog.csdnimg.cn/direct/869d671c3ce8448dab5f2394f41c974e.png) ### 1.5 报文分片 ![](https://i-blog.csdnimg.cn/direct/7bac4bb3849b4cf0b6b4e2ee8a10e4ec.png) 我们前面的博客,可以看见,对应一个4000大小的滑动窗口还进行了分区,每个区的大小为1000,原因就是数据链路层的设定(后续详细讲解) 数据链路层:从上层接受下来的完整报文,大小不超过MTU,最大传送单元,一般是1500字节(但数据是1460字节,因为ip和tcp报头还要各占40字节),为什么? 并且数据链路层只通知,不分片,分片由你网络层完成,同样的,组装也由对端的网络层完成 举个例子,加强理解 > 你有1台10公斤的电脑,打算寄快递发给你的朋友,但快递公司说,他们最多一个快递寄3公斤,你为了寄出,只能进行拆分 分片,同样的,组装也是由你朋友收到快递后进行组装 *** ** * ** *** 结论一:网络通信的过程,如果过多分片,就会导致丢包率 但分片和组装不是主流,要减少,而主要收传输层传输有关 #### 1.5.1 学习分片和组装 ![](https://i-blog.csdnimg.cn/direct/c42bd7c7168d427bbaf08ad0517e34f1.png) 分片与组装主要用到上面表格中的第二行 > • 16位标识(id): 唯⼀的标识主机发送的报⽂. 如果IP报⽂在数据链路层被分⽚了, 那么每⼀个⽚⾥⾯的这个id都是相同的. (不同报文,标识不同,相同报文,标识相同) > • 3位标志字段: 第⼀位保留(保留的意思是现在不⽤, 但是还没想好说不定以后要⽤到). 第⼆位置为1 表⽰禁⽌分⽚, 这时候如果报⽂⻓度超过MTU, IP模块就会丢弃报⽂. 第三位表⽰"更多分⽚", 如果 分⽚了的话, 最后⼀个分⽚置为0, 其他是1. 类似于⼀个结束标记. > • 13位分⽚偏移(framegament offset): 是分⽚相对于原始IP报⽂开始处的偏移. 其实就是在表⽰当 前分⽚在原报⽂中处在哪个位置. 实际偏移的字节数是这个值 8 得到的. 因此, 除了最后⼀个报⽂之外, 其他报⽂的⻓度必须是8的整数倍(否则报⽂就不连续了). *** ** * ** *** 1. 如何确定特定报文是否被分片? > 1.更多分片是否是1,如果是1,就是分片 > > 2.更多分片是否为0,如果是0且13位偏移量不为0,那就是分片 2.怎么确保自己把分片收全了 > a.相同的标识的分片,聚合在一起! > > b.怎么保证你收全了? 反过来想,怎么确定没有收全? 1.第一片丢失 即一个标识符的切片,没有偏移量为0的切片 2,中间片丢失 > 把收到的所有分片,按照片偏移量进行升序排序! > > 片偏移+自身报文的长度=下一个分片的片偏移数字 3. 结尾丢失 没有更多分片为0的 所有组装则是与分片相反,不再赘述 *** ** * ** *** #### 1.5.2 细讲补充 > 1.如何尽可能确保不会分片? > > 在三次握手时,两端就会交换各自的数据链路层的MTU,进行比较,以最小的为上限 > > 2.在网络转发的过程中,可能会遇到MTU更小的,此时就会再进行分片

相关推荐
Fanfanaas1 小时前
Linux 系统编程 进程篇 (三)
linux·运维·服务器·c语言·单片机·学习
Rsun045511 小时前
13、Java 策略模式从入门到实战
java·bash·策略模式
半壶清水1 小时前
[软考网规考点笔记]-局域网之VLAN
网络·笔记·网络协议·tcp/ip
九天鸟1 小时前
ESXI里面虚拟机服务器始终保持免用户认证状态
linux·运维·centos
Just right1 小时前
pycharm卡死在Connected to pydev debugger
ide·python·pycharm
aq55356001 小时前
Laravel2.x:被遗忘的PHP框架遗珠
开发语言·汇编·c#
青城山下————1 小时前
CentOS 7 安装 Redis(使用默认 6379 端口)完整实践与踩坑总结
linux·redis·centos
汽车仪器仪表相关领域1 小时前
GT-NHVR-20-A1工业及商业用途点型可燃气体探测器:精准感知隐患,筑牢工商业安全防线
运维·网络·人工智能·功能测试·单元测试·汽车·压力测试
光泽雨1 小时前
c#对object sender ,EventArgs e 的解释
开发语言·c#