添加 IP协议

This commit is contained in:
BaiMeow
2023-08-03 01:02:40 +08:00
parent 80b0e02042
commit 67547eaf1a
5 changed files with 210 additions and 4 deletions

View File

@@ -0,0 +1,185 @@
# IP协议
> Author: 柏喵樱
>
> copyright reserved
## IP 协议数据包结构
IP 协议是网络层最主要的协议几乎所有的上层数据包都需要IP协议的承载我们网络层的第一块内容将从 IP 协议讲起。
下图展示了 IP 协议的报文头部格式,这张图每行代表 32 个 bit也就是 4 个字节byte。如果不计算 Options 这种可选项的话IP 协议的报头长度为 20 个字节。
在头部的后面会携带负载payload这个词可能略显晦涩但实际上就是我们需要发送的数据。
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Example Internet Datagram Header
</pre>
## 版本
第一个字段是IP协议版本号用于标识IPv4和IPv6两个版本这两个版本的报文格式是不同的。上图展示的是 IPv4 的报文格式
## IHLInternet Header Length
就是IP协议的头部部分的长度单位是 4byte由于 IP 头一般长度为 20byte所以这个值一般为 5。如果存在Options字段这个值会相应增加。
## Type of Service
服务类型,标记服务类型最初是为了对不同服务的数据包做不同的转发策略,比如说哪些数据包应该被优先转发,应该更注重转发延时还是更注重吞吐量一类的问题,除非到运营商层面一般接触不太到。
## 数据包总长度
Total Length 很好理解就是包括 IP 头在内的 IP 报文的总长度,报文长度上限就是 MTU。
## Identification & Flags & Fragment Offset
这三个字段放在一起讲,他们都是用于控制分片的。
我们的 MTU 他一般是 1500去除 20 bytes 的头部他还能够携带 1480 bytes 的数据,但是现实中的负载很容易就能够超出这个大小,这时候就需要将内容切片分块发送。
切片时,会切出许多 1480 bytes 的切片,和剩下的不足 1480 bytes 的部分。对于以上的所有切片,都会给他们加一个自己的 IP 头。这些 IP 头有一个共同点,就是他们具有一个相同的 Identification 用于识别identify他们原先是一块的。
现在还存在两个问题,
1. 服务器接收到一个分片后,不知道要不要继续接收
2. 分片很有可能乱序抵达,服务器不知道分片的顺序
对于第二个问题,引入了 Fragment Offset分片偏移量他的单位是 byte用于标识这一个分片的数据是从原来超长负载的哪个位置开始的。比如对于一个长度为 5000 bytes 的负载,他的几个分片的 Fragment Offset 依次为 0,1480,2960,4440。在收到数据后服务器只需要按照这个字段重新组装即可。
对于第一个问题,引入了 Flags标志位, Flags 里有三个 Flag其中最后一位的意义是“后面还有更多分片“这就相当于告诉服务器你要继续等待接收其他分片。而当最后的分片抵达时服务器在知道这是最后的分片的同时他也能从这个分片的 Fragment Offset里得知前面应该有多少数据如果缺失服务器也能继续等待接收。
关于Flags的其他两位最高位是目前保留不使用永远为0。后面那位的意义是不要分片这一般是不设置的他这句话是对传输过程中的路由设备讲的因为如果途径 MTU 低于当前包长度的链路可能会进行二次分片。如果设置了这个 Flag转发时再碰到 MTU 低的链路这种包会被直接丢弃同时返回一个 ICMP 包告诉源IP地址的设备发生了什么。
## TTL(Time To Live)
TTL 是一个unsigned int代表数据包的剩余生存时间指的是数据包在互联网中还能转发多少时间单位是秒。
虽然单位是秒,但是一般情况下转发耗时是远远低于一秒的,根据 IP 协议的规定无论转发耗时多少TTL 应当至少 -1所以在实践中 TTL 往往指的是转发了几次。
一般发往互联网的数据包初始 TTL 为 64 或 128你可以试试 ping 命令他会显示一个TTL这是对面服务器回复的包到自己的设备的时候的 TTL。
```powershell
PS C:\Users\bs> ping baidu.com
正在 Ping baidu.com [39.156.66.10] 具有 32 字节的数据:
来自 39.156.66.10 的回复: 字节=32 时间=43ms TTL=47
来自 39.156.66.10 的回复: 字节=32 时间=144ms TTL=47
来自 39.156.66.10 的回复: 字节=32 时间=43ms TTL=47
来自 39.156.66.10 的回复: 字节=32 时间=42ms TTL=47
39.156.66.10 Ping 统计信息:
数据包: 已发送 = 4已接收 = 4丢失 = 0 (0% 丢失)
往返行程的估计时间(以毫秒为单位):
最短 = 42ms最长 = 144ms平均 = 68ms
```
TTL 减少到 0 的时候这个数据包会被丢弃所以如果互联网中出现路由配置错误以至于产生了一个环TTL 能够帮助数据包及时停止转发,避免事故扩大最终导致网络设施瘫痪。
当路由设备由于 TTL 为 0而丢弃这个数据包的时候路由设备还会向源 IP 回复一个 `TTL超时`的 ICMP 报文
```powershell
PS C:\Users\bs> ping baidu.com -i 2
正在 Ping baidu.com [39.156.66.10] 具有 32 字节的数据:
来自 192.168.1.1 的回复: TTL 传输中过期
来自 192.168.1.1 的回复: TTL 传输中过期
来自 192.168.1.1 的回复: TTL 传输中过期
来自 192.168.1.1 的回复: TTL 传输中过期
39.156.66.10 Ping 统计信息:
数据包: 已发送 = 4已接收 = 4丢失 = 0 (0% 丢失)
```
traceroute 就是利用这个性质来实现的,通过从 0 开始遍历 TTL 的方式,可以拿到转发过程中的所有路由器的 ICMP 回复,从这些回复中可以读取到这些路由器的 IP。
当然 traceroute 不是万能的,真实互联网中广泛存在拦截,不响应 ,改写等等行为,会导致 traceroute 产生丢失或者藏跳等等比较迷惑的结果。
```powershell
PS C:\Users\bs> TRACERT.EXE bilibili.com
通过最多 30 个跃点跟踪
bilibili.com [8.134.50.24] 的路由:
1 8 ms 13 ms 2 ms 192.168.0.1 [192.168.0.1]
2 1 ms 1 ms 2 ms 192.168.1.1 [192.168.1.1]
3 8 ms 8 ms * 100.66.0.1
4 * * * 请求超时
5 * * * 请求超时
6 * * * 请求超时
7 * * * 请求超时
8 * * 8 ms 61.139.121.77
9 * * * 请求超时
10 78 ms * * 113.96.5.134
11 * 83 ms 43 ms 121.14.50.241
12 45 ms 42 ms 41 ms 121.14.24.82
13 * * * 请求超时
14 * * * 请求超时
15 * * * 请求超时
16 * * * 请求超时
17 42 ms 50 ms 40 ms 8.134.50.24
跟踪完成
```
上面就是一个真实案例,有很多路由设备在丢弃数据包时并没有给出 ICMP 回复。
## 协议
协议Protocol指的是负载中的数据所使用的协议。这就很广泛了比如
- TCP
- UDP
- ICMP
- Telnet
- OSPF
具体可以参考 [List of IP protocol numbers - Wikipedia](https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers)
## 头部校验和
头部校验和Header Checksum用于检验传输的数据是否出错一旦出错直接丢弃。
在计算头部的校验和的时候,头部校验和这个字段会被置零,再使用特定算法计算得到校验和,填写到这个位置。
这个校验和算法比较简单,就是头部以 16 bits 为单位,取补码再求和
注意,由于 TTL 在每次转发中都会改变,所以实际上,每次转发都会重新计算校验和。
## IP地址
正如上图的 `Source Address``Destination Address` 字段所展示的一样,一个 IP 地址占用 4 byte 的存储空间。在书面的写法上,我们用 `.` 将每一个 byte 分割开,例如 `1.1.1.1` 这样更便于人类处理和分类。
有一些 IP 地址被用作特殊用途,除了这些 IP 地址外的地址都是公网 IP一个公网 IP 在整个互联网范围内按照规范来说只能由一台网络设备占有也有例外anycast。但互联网是复杂的也有人占用这些地址作为自己的内网地址例如 tr069这个由网络运维人员自行分析情景把握。
网络地址的分类需要更多的前置知识,我们后续再介绍。
## 可选项
可选参数Options比较繁琐一般没啥用有兴趣的可以看看下面参考资料中 RFC 791 对此的描述。
## 参考资料
- [RFC 791 - Internet Protocol (ietf.org)](https://datatracker.ietf.org/doc/html/rfc791)
- [Reserved IP addresses - Wikipedia](https://en.wikipedia.org/wiki/Reserved_IP_addresses)
- [List of IP protocol numbers - Wikipedia](https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers)

View File

@@ -0,0 +1,18 @@
# 9.2.3 网络层
> Author: 柏喵樱
>
> copyright reserved
本章节是网络层的开篇章节,我们先做两个约定:
- 没有提及IP协议版本都是IPv4 IPv6 会单独介绍不详细展开)
- 路由表已经配置好了给IP地址就能发到正确的地方路由技术参照“路由与交换”章节
以上两个约定适用于所有网络层章节。
在链路层我们已经实现了两个直接相连的设备之间的数据收发,也可以在总线类型的网络上完成数据手法,更成熟一点,可以借助交换机来构建一个具有一定规模的中心化网络。
但中心化是有极限的这必然无法承载这个整个互联网因此我们需要再往上一层定义一个新的概念IP 地址,并完成实现数据包的转发操作,将互联网推向去中心化。

View File

@@ -1 +0,0 @@
# 9.2计网基础

View File

@@ -95,7 +95,7 @@
链路层 ---> 数据帧/MAC/CRC
链路层 ---> PPP
链路层 ---> ARP
网络层 ---> IP地址
网络层 ---> IP 协议
网络层 ---> 子网/掩码/CIDR
网络层 ---> IPv6概述
传输层 ---> 端口