Network - 03.Network Layer-01
- 主要任务: 将数据报 (datagrams) 从源主机跨越多个网络路由 (routing) 到目标主机。
- 逻辑寻址 (Addressing): 定义全局唯一的 IP 地址(如 IPv4、IPv6)来标识网络中的主机 。
- 路由 (Routing): 决定数据包从源到目标的最佳路径。这是通过路由算法(如链路状态算法 或距离向量算法 )实现的。
- 转发 (Forwarding): (讲稿第 4 章内容) 路由器根据转发表将数据包从输入端口移动到正确的输出端口。
- 数据报封装: 将来自传输层的报文段 (segment) 封装成数据报 (datagram) 。
- 地址管理: CIDR 和路由地址聚合 用于高效管理地址空间。
第 4 章:网络层 (Chapter 4: Network Layer)
4.1 简介 (Introduction)
网络层 (Network Layer) 的主要任务是实现主机到主机 (host-to-host) 的通信。它负责将报文段 (segment)(来自传输层的数据单元)从源主机安全、准确地传输到目的主机。
* 主机到主机通信:与传输层负责的进程到进程通信不同,网络层关注的是将数据从一台计算机发送到另一台计算机,而不关心这些数据最终是由哪个应用程序接收的。
* 无处不在:网络是互联网的核心,因此网络中的每一个主机 (host) 和每一个路由器 (router) 都必须实现网络层协议。
1. 网络层的功能
- 发送端主机:
- 网络层从上层的传输层接收报文段 (segment)。
- 它将这些报文段进行封装 (encapsulates),即在报文段前面加上网络层的首部信息(如源IP地址、目的IP地址等),形成数据报 (datagram)。
- 封装好的数据报随后被传递给链路层进行发送。
- 网络中的路由器:
- 当一个数据报到达路由器的输入链路时,路由器的网络层会检查数据报的首部字段。
- 通过检查首部中的目的地址,路由器决定将该数据报转发到哪个输出链路。
- 接收端主机:
- 当数据报到达目的主机时,网络层接收该数据报。 *它会去掉网络层首部,取出其中的报文段,并将其向上递交给传输层。
2. 两个关键功能:转发与路由
- 转发 (Forwarding):
- 定义:转发(有时也称为交换 Switching)是指将数据包从路由器的输入接口移动到适当的输出接口的过程。
* 性质:这是一个在单个路由器内部发生的本地 (local) 动作。 - 层面:转发是在数据平面 (Data Plane) 上执行的。数据平面指的是路由器中负责实际处理和传送用户数据报的部分。
- 实现:转发通常必须非常快(纳秒到微秒级别),因此通常由专用硬件来完成。路由器通过查询其内部的转发表 (forwarding table) 来决定将数据报发送到哪个输出端口。
- 定义:转发(有时也称为交换 Switching)是指将数据包从路由器的输入接口移动到适当的输出接口的过程。
- 路由 (Routing): 决定数据包从源到目标所采用的路径。这是在“控制平面”(Control Plane)上执行的全局操作。
* 定义:路由是指确定数据包从源主机到目的主机所经过的整体路径的过程。- 性质:这是一个涉及整个网络的全局 (global) 动作。它需要了解网络的拓扑结构和链路状态。
- 层面:路由是在控制平面 (Control Plane) 上执行的。控制平面负责管理网络的逻辑和决策,它决定了数据报应该如何流动。
- 实现:路由通常通过在路由器上运行复杂的路由算法 (Routing algorithms) 来实现。这些算法计算出最佳路径,并据此填充和更新路由器的转发表。路由计算的时间尺度通常比转发要慢得多(秒到分钟级别),并且通常由软件实现。
- 路由算法 (Routing algorithms) 决定了路由器的转发表 (forwarding table)。路由算法生成 路由表 (RIB) 经过优选和编译 生成 转发表 (FIB)。
比喻:
- 路由 (Routing) 就像是规划一次从源头到目的地的完整旅行路线。
- 转发 (Forwarding) 就像是在一个交叉路口(路由器)决定从哪条路(输出端口)离开。
3. 连接建立 (Connection Setup)
- 某些网络架构(如 ATM, X.25)中存在连接建立 (Connection setup)。
- 在数据流开始前,端系统和中间的路由器会建立虚连接 (virtual connection)。
- 这与传输层的连接(进程到进程)不同,网络层的连接是主机到主机 (host-to-host) 的。
4. 网络服务模型 (Network Service Model)
- 网络服务模型本质上是网络(快递公司)和用户(发件人)之间的一份 “服务合同”。它定义了当你把一个数据包(包裹)交给网络后,网络承诺会如何对待这个包裹。在这个“合同”里,可能会包含以下条款:
- 确保送达吗? (Guaranteed delivery) —— 丢件了赔不赔?
- 有时限吗? (Delay) —— 承诺3天内必达吗?
- 不仅送达,还要按顺序吗? (In-order) —— 我发了包裹A和包裹B,你能保证A先到,B后到吗?
- 带宽保证吗? (Bandwidth) —— 能给我预留一条专用车道,确保我不堵车吗?
- 服务示例:
- 单个数据报: 保证交付 (guaranteed delivery)、带延迟上界的保证交付 (guaranteed delivery with delay)。
- 数据流: 按序数据报交付 (in-order datagram delivery)、保证最小带宽 (guaranteed minimum bandwidth)。
- 互联网 (Internet) 的服务模型是 尽力而为 (best effort):
- 不保证带宽 (Bandwidth)
- 不保证不丢包 (Loss)
- 不保证按序 (Order)
- 不保证时序 (Timing)
- ATM 提供了多种服务模型,如 CBR (恒定比特率)、VBR (可变比特率) 等,提供严格的保证。
- ATM (Asynchronous Transfer Mode) 是老一代的电信网络技术(主要用于电话网核心)
- CBR (Constant Bit Rate,恒定比特率):
- 就像传统的电话线路。网络承诺:“我给你预留一条 64kbps 的专用通道,不管网络多忙,这条通道都是你的,延时极低且固定。”这非常适合传输语音,但如果没人说话,这带宽就浪费了。
- VBR (Variable Bit Rate,可变比特率):
- 允许速率在一定范围内波动,但依然有严格的平均带宽和延迟保证。
4.2 虚电路和数据报网络 (Virtual Circuit and Datagram Networks)
网络层可以提供两种服务:
- 数据报网络 (Datagram network) 提供网络层的无连接服务 (connectionless service)。
- 虚电路网络 (Virtual circuit network) 提供网络层的连接服务 (connection service)。
1. 虚电路 (Virtual Circuits - VCs)
- VC 网络的行为类似于电话电路,在数据传输前需要建立连接。
- 流程: 1. 呼叫建立 (call setup) -> 2. 数据流动 -> 3. 呼叫拆除 (teardown)。
- 每个数据包携带 VC 标识符 (VC identifier),而不是目的主机地址。
- 路径上的每个路由器都为通过的连接维护状态 (state)。
- 信令协议 (Signaling protocols) (如 ATM, X.25) 用于建立、维护和拆除 VC。
- 互联网不使用信令协议。
2. 数据报网络 (Datagram Networks)
- 这是互联网采用的模式。
- 网络层没有呼叫建立 (no call setup)。
- 路由器不维护 (no state) 关于端到端连接的状态。
- 数据包使用目的主机地址 (destination host address) 进行转发。
- 同一源-目标对之间的数据包可能走不同路径。
- 转发表 (Forwarding table) 是基于目的地址范围的。存储的是前缀
- 最长前缀匹配 (Longest prefix matching): 路由器在转发表中查找与数据包目的地址匹配的“最具体”的条目(即前缀最长的条目),并据此转发。
- 通过这种方式,路由器的转发表可以非常紧凑和高效。它不需要知道 40 亿个地址,它可能只需要几万到几十万个“前缀”(即地址范围)就能覆盖整个互联网的路由。
3. 对比:数据报 vs. 虚电路
| 特性 | 数据报网络 (Internet) | 虚电路网络 (ATM) |
|---|---|---|
| 设计目标 | 计算机数据交换(弹性服务) | 电话网演进(严格时序) |
| 端系统 | “智能” (Smart end systems) | “哑” (Dumb end systems) |
| 复杂性 | 在“边缘” (complexity at “edge”) | 在“内部” (complexity inside network) |
4.3 路由器内部 (What’s Inside a Router)
1. 路由器架构 (Router Architecture)
- 路由处理器 (Routing processor): (运行在控制平面)
- 执行路由协议(如 OSPF, BGP)。
- 维护路由表。
- 计算转发表。
- 交换与转发: (运行在数据平面)
- 输入端口 (Input port)
- 交换结构 (Switching fabric)
- 输出端口 (Output port)
2. 输入端口 (Input Port)
- 功能:
- 物理层:接收比特。接收光纤或网线传来的光电信号,把它们还原成 0 和 1 的比特流。
- 数据链路层:解封装。从以太网帧头取出里面的 IP 数据包。
- 网络层:查找转发表,决定输出端口。
- 去中心化交换 (Decentralized switching): 路由处理器把计算好的“转发表”,复制一份给每一个输入端口。在输入端口本地维护一份转发表的副本,以实现线速 (line speed) 处理,避免路由处理器成为瓶颈。
- 如果数据报到达速度快于转发速率,会发生队列 (queuing)。
3. 交换结构 (Switching Fabric)
-
功能: 将数据包从输入端口连接到输出端口。
-
三种类型:
- 通过内存交换 (Switching Via Memory):
- 第一代路由器。由 CPU 控制。
- 数据包需要两次穿过系统总线(输入->内存,内存->输出)。
- 速度受限于内存带宽。
- 通过总线交换 (Switching Via a Bus):
- 输入端口通过共享总线将数据报传输到输出端口。
- 速度受限于总线带宽,存在总线竞争 (bus contention)。
- 通过互连网络交换 (Switching Via An Interconnection Network):
- 例如纵横式交换机 (crossbar switch)。
- 克服总线带宽限制,可并行转发多个数据包。
- 通过内存交换 (Switching Via Memory):
4. 输出端口 (Output Port)
- 功能:
- 网络层:排队(缓冲区管理)。
- 缓冲区管理:这是输出端口最忙碌的工作。如果交换结构送来的包太快,而外面的网线(链路)发得太慢,数据包就必须在这里排队。
- 丢包:如果缓冲区(排队大厅)满了,新来的数据包就会被无情地丢弃(Packet Drop)。
- 数据链路层:封装(添加头部和尾部)。
- 数据包在路由器内部“裸奔”(只有 IP 内容)。在发出去之前,必须给它穿上“外套”。
- 比如,如果出口连的是以太网,就要加上以太网帧头 (Header) 和 帧尾 (Trailer)。
- 物理层:发送比特。
- 这是最后一步。将封装好的帧(Frame)转换成光信号或电信号,推送到网线上。
- 网络层:排队(缓冲区管理)。
- 缓冲 (Buffering) 是必需的:当数据报从交换结构到达的速率快于输出链路的传输速率时。
- 调度策略 (Scheduling discipline) 决定了在队列中选择哪个数据包进行下一次传输(例如 FIFO 或
WFQ)。- FIFO (First-In-First-Out, 先进先出):
- 最简单:大家按顺序排队,谁先来谁先走。
- 缺点:不灵活。如果前面有个巨大的数据包在传,后面紧急的语音通话数据包也得干等(导致语音卡顿)。
- 优先级队列 (Priority Queuing):
- VIP 通道:给数据包分类。比如,标记为“VoIP 语音”或“网络管理”的包属于高优先级。
- 机制:只要高优先级队列里有包,就先发高优先级的;只有高优先级空了,才发普通优先级的(如邮件、下载)。
- WFQ (Weighted Fair Queuing, 加权公平队列):
- 相对公平:它把排队的包按“流 (Flow)”(比如视频流、网页流)分开。
- 机制:各个流轮流发送,但是权重不同。比如给视频流分配 50% 的带宽,给网页流分配 20%。这样既保证了关键业务,又不会让低优先级的业务完全饿死。
- FIFO (First-In-First-Out, 先进先出):
5. 队列 (Queuing)
- 队列发生的位置: 输入端口和输出端口都可能发生。
- 缓冲区大小 (Buffering Size):
- 传统经验法则 (RFC 3439): 缓冲区大小 (往返时间 * 链路容量)。
- 近期推荐: (N 为流的数量)。
- 输入队列的队头阻塞 (Head-of-the-Line (HOL) blocking):
- 当输入队列的第一个数据包(例如,一个红色的包)因其目标输出端口忙碌而被阻塞时,它会阻止队列中后续的数据包(例如,一个绿色的包),即使绿色包的目标输出端口是空闲的。
- 输出端口的队列:
- 当多个输入端口同时向同一个输出端口发送数据包,且速度超过输出链路容量时,会在输出端口形成队列。
4.4 IP:互联网协议 (IP: Internet Protocol)
互联网网络层
互联网网络层相关的三个主要协议:
- IP 协议 (IP protocol): 寻址、数据报格式、分片等。网络层只有这一个协议
- 路由协议 (Routing protocols): 路径选择 (如 RIP, OSPF, BGP)。
- ICMP 协议 (ICMP protocol): 错误报告、网络查询。
4.4.1 IP 数据报格式 (IPv4 Datagram Format)
- 版本 (Version): 4 (表示 IPv4)。
- 首部长度 (Header length): IP 头部的长度(以 32 位字为单位即4字节)。
- 总长度 (Total length): 整个数据报(首部 + 数据)的长度(以字节为单位)。
- 标识 (Identifier), 标志 (Flags), 片偏移 (Fragment offset): 这三个字段用于 IP 分片。
- 标识 (Identifier): 16 bits。主机发送的每个数据报都有唯一的 ID。当数据报被分片时,所有分片都复制同一个 ID,以便接收方能将它们识别为同一个原始包。
- 标志 (Flags): 3 bits。
- Bit 0: 保留。
- Bit 1: DF (Don’t Fragment)。如果置 1,强制路由器不要分片(如果包太大传不过去,路由器只能丢包并报错)。
- Bit 2: MF (More Fragments)。如果置 1,表示后面还有分片;如果置 0,表示这是最后一个分片。
- 片偏移 (Fragment Offset): 13 bits。指示当前分片在原始数据报中的位置。用于接收方将乱序到达的分片重新拼装。
- 生存时间 (Time to Live - TTL): 数据包在网络中可通过的最大跳数。每经过一个路由器减 1,若减到 0,则丢弃该包(防止无限循环)。
- 目的: 防止路由环路(Routing Loop)。如果路由表配置错误导致数据包在网络中无限兜圈子,TTL 最终会减为 0。
- 上层协议 (Upper layer protocol): 指示负载 (payload) 应交付给哪个传输层协议(例如 TCP (6) 或 UDP (17))。
- 首部校验和 (Header checksum): 仅对头部进行校验。每经过一个路由器都会重新计算(因为 TTL 字段会改变)。(数据部分的校验由 TCP/UDP 自己负责)因为 TTL 字段在每经过一个路由器时都会改变,所以校验和必须在每个路由器上重新计算。
- 源 IP 地址 (Source IP address): 32 位。
- 目的 IP 地址 (Destination IP address): 32 位。
- 选项 (Options): (可选) 用于时间戳、记录路由等。
- 开销 (Overhead):
- 一个典型的 IP 头部有 20 字节 (没有选项时)。
- 一个典型的 TCP 头部有 20 字节。
- 因此,传输数据至少有 40 字节的头部开销。
- 意义: 如果你只发送 1 个字节的数据(例如 Telnet 按键),实际需要传输 41 字节。这就解释了为什么在流媒体或游戏中,我们倾向于尽量填满数据包载荷,以提高带宽利用率。
网络层的功能是从主机到主机的,而不是从进程到进程的,所以没有端口号。
IP 分片与重组 (IP Fragmentation & Reassembly)
- 最大传输单元 (Max Transfer Unit - MTU): 链路层帧能承载的最大数据量。
- 分片 (Fragmentation): 当一个 IP 数据报大于链路的 MTU 时,路由器会将其分割成多个较小的数据报(分片 (fragments))。
- 重组 (Reassembly): 只在最终目的地 (final destination) 进行。
- 示例: 一个 4000 字节的数据报(20 字节头 + 3980 字节数据)在 MTU=1500 字节的链路上分片:
- 片 1: 1500 字节(20 字节头 + 1480 字节数据)。
fragflag=1(表示还有更多分片)offset=0
- 片 2: 1500 字节(20 字节头 + 1480 字节数据)。
fragflag=1offset=185(偏移量以 8 字节为单位, )
- 片 3: 1040 字节(20 字节头 + 1020 字节数据)。
fragflag=0(表示这是最后的分片)offset=370()
- 片 1: 1500 字节(20 字节头 + 1480 字节数据)。
| 分片 | 数据部分 (Bytes) | 头部 (Bytes) | 总长度 (Total Length) | 标志 (MF) | 偏移 (Offset) | 实际对应的原始字节位置 |
|---|---|---|---|---|---|---|
| 片 1 | 1480 | 20 | 1500 | 1 (还有) | 0 | 0 ~ 1479 |
| 片 2 | 1480 | 20 | 1500 | 1 (还有) | 185 | 1480 ~ 2959 |
| 片 3 | 1020 | 20 | 1040 | 0 (没了) | 370 | 2960 ~ 3979 |
之所以容易混淆,是因为在计算中出现了两次“20 字节”:
- 原始包的 20 字节:这是原始 IP 头部。我们在计算 Payload 时把它减掉了 ()。
- 分片时的 20 字节:这是新生成的 IP 头部。我们在计算每个分片能装多少数据时把它减掉了 ()。
题目中看到的“20 字节头”,在分片计算的语境下,始终指的是 IP 协议的头部。TCP 头部在这个过程中被当成了数据的一部分,被切分到了第一个分片里。
4.4.2 IPv4 寻址 (IPv4 Addressing)
1. IP 地址 (IP Address) 与 接口 (Interface)
- 核心定义: IP 地址并不直接标识一台“主机”或“路由器”,而是标识它们的一个接口 (Interface)。
- 主机 (Host): 通常有一个或两个接口(例如有线网卡 + 无线网卡),每个接口都需要一个独立的 IP 地址。
- 路由器 (Router): 路由器的工作就是在不同网络间转发数据,因此它必须至少有两个或更多的接口。每个接口连接到一个不同的网络,因此每个接口都有一个属于该特定网络的 IP 地址。
- 直观理解: IP 地址就像是“门牌号”。路由器像是一座连接多条街道(网络)的建筑物,它在每条街道上都有一个大门(接口),每个大门都需要挂上对应街道的门牌号。
2. 子网 (Subnet)
子网是理解 IP 网络的基石。
-
什么是子网?
- 物理层面: 想象一个“孤岛”。如果你把路由器的电源拔掉,甚至把路由器从网络中移除,剩下的设备如果仍然能够通过交换机(Switch)或直接连线互相通信(发送以太网帧),那么这些设备就构成了一个子网。
- 逻辑层面: 属于同一个子网的接口,其 IP 地址的网络前缀 (Network Prefix) 部分必须完全相同。
-
子网掩码 (Subnet Mask) 的作用:
- 计算机无法通过肉眼判断 IP 地址哪部分是网络号,哪部分是主机号。子网掩码就是一把“尺子”,用来划分界限。
- 例如:
255.255.255.0(二进制为 24 个 1) 告诉计算机,IP 地址的前 24 位是子网部分,剩下的 8 位是主机部分。
-
如何判断一个网络中有几个子网?
- 方法: 找到网络拓扑图中的每一个路由器接口。以该接口为中心,向外发散,直到碰到其他路由器接口或终点(主机)。这一片区域就是一个子网。
- 注意: 两个路由器之间的点对点链路(Point-to-Point Link)本身也是一个独立的子网。
3. CIDR (Classless InterDomain Routing) —— 无类域间路由
这是现代互联网分配 IP 地址的标准,它废除了早期死板的 A类、B类、C类 地址划分。
- 表示法:
a.b.c.d/xx称为前缀长度。- 前 x 位: 是网络部分(子网 ID)。这部分一旦确定,该子网内所有设备的前 x 位必须一样。
- 后 (32-x) 位: 是主机部分。用于区分子网内的不同设备。
- 计算能力:
- 子网大小: 一个
/x的子网可以容纳 台主机。 - 为什么要减 2? 因为主机号全为 0 的地址代表本网络地址,主机号全为 1 的地址代表本子网广播地址,这两个不能分配给具体设备。
- 示例:
/24子网(即掩码 255.255.255.0)有 位主机号。可分配地址为 个。
- 子网大小: 一个
4. 层次化寻址与路由聚合 (Route Aggregation)
这是为了解决互联网路由表过于庞大而设计的机制,也称为超网 (Supernetting)。
-
问题背景:
- 假设一个 ISP(互联网服务提供商)拥有 8 个连续的
/24小网段。如果它向全球互联网通告这 8 个独立的路由信息,全球所有核心路由器的路由表都会增加 8 行。这非常浪费资源。
- 假设一个 ISP(互联网服务提供商)拥有 8 个连续的
-
解决方案 (路由聚合):
- ISP 就像一个大的邮局分拣中心。它不告诉外界“我这里有A小区、B小区、C小区…”,而是直接告诉外界“所有邮编开头是 100xxx 的信件都给我”。
- 技术实现: 将这 8 个小网段的共同前缀提取出来,合并成一个更短前缀(例如
/21)的大块地址。 - ISP 只向外界通告这一个
/21的聚合路由。
-
最长前缀匹配 (Longest Prefix Match):
- 如果路由表中存在一条聚合路由(例如
200.23.16.0/20,指向 ISP A)和一条特例路由(例如200.23.18.0/24,指向 ISP B),当数据包的目标是200.23.18.1时,路由器会优先选择掩码最长(匹配最精确) 的那条路(即/24指向的 ISP B)。这就是为什么聚合不会导致特例路由失效。
- 如果路由表中存在一条聚合路由(例如
5. ICANN 的角色
- 全称: Internet Corporation for Assigned Names and Numbers。
- 职责: 它是互联网的“大管家”。
- 分配 IP 地址: 它不直接给个人分 IP,而是把大块的 IP 地址块分配给区域互联网注册机构 (RIRs,如亚太区的 APNIC)。
- 管理 DNS 根域: 确保全球域名解析系统的根基稳定。
6. DHCP:动态主机配置协议 (DHCP: Dynamic Host Configuration Protocol)
- 功能: 允许主机在加入网络时从服务器动态获取 (dynamically obtain) 其 IP 地址。
- DHCP 交互过程 (D-O-R-A):
- Discover (发现): 主机广播 “DHCP discover” 消息。(源: 0.0.0.0, 目的: 255.255.255.255)
- Offer (提供): DHCP 服务器响应 “DHCP offer” 消息,提供一个 IP 地址及租期。
- Request (请求): 主机广播 “DHCP request” 消息,请求所提供的地址。
- Ack (确认): DHCP 服务器发送 “DHCP ack” 消息,确认地址分配。
- 后两步使用广播(Broadcast)看起来似乎效率不高,但它们是 DHCP 协议设计中非常关键的环节,主要是为了解决潜在的冲突和确保消息的可靠传递。
-
通知“中选”的服务器(服务器 A): “我确定要用你提供的 IP 地址!”
-
通知所有“落选”的服务器(服务器 B): “我不要你们的 IP 地址了!” 这样,其他服务器(服务器 B)就可以收回它们之前保留的 IP 地址(192.168.1.150),并将其分配给其他需要的主机。
-
如果服务器将
Ack单播(直接发送)到那个新分配的 IP 地址(例如223.1.2.4),主机的网络功能可能还没有完全准备好接收发往这个新地址的数据包。这个Ack很可能会丢失。 -
因此,服务器采用最稳妥的方式:广播
Ack消息 。 -
主机此时仍然在监听来自 0.0.0.0 的广播消息。当它收到这个
Ack广播时,它会检查消息中的事务 ID (Transaction ID) 和自己的 MAC 地址,确认是发给自己的,然后才正式将223.1.2.4这个 IP 地址配置到自己的网络接口上
-
7. NAT:网络地址转换 (NAT: Network Address Translation)
- 动机:
- 本地网络(如家庭网络)对外界只使用一个 IP 地址。
- 解决了 IPv4 地址短缺问题。
- 安全性: 本地网络中的设备对外界不可见/不可寻址。
- 实现: NAT 路由器维护一个 NAT 转换表 (NAT translation table)。
- 出站数据报: 路由器用(NAT IP 地址, 新端口号)替换(源 IP 地址, 源端口号)。
- 入站数据报: 路由器根据 NAT 表,用(原始源 IP 地址, 原始端口号)替换目的地的(NAT IP 地址, 新端口号)。
- 为什么需要端口号?
- NAT 路由器的 WAN 口(对外)通常只有一个公共 IP 地址(这里是
138.76.29.7)。 - 但是 LAN(内网)里有很多台电脑(
10.0.0.1,10.0.0.2,10.0.0.3)。 - 如果只转换 IP 地址,当外网的数据回来时,路由器不知道该把数据给哪台内网电脑。
- 解决方案:路由器使用 端口号 来区分不同的内网连接。它把内网的
IP:端口映射为外网的公网IP:新端口。 - 图中 NAT 表的意思是:凡是发往
138.76.29.7且端口号是5001的数据包,都要转发给内网的10.0.0.1的3345端口。
- NAT 路由器的 WAN 口(对外)通常只有一个公共 IP 地址(这里是
- 争议:
- 路由器本应只处理到第 3 层(网络层),但 NAT 触及了第 4 层(传输层)的端口号。
- 违反了端到端论点 (end-to-end argument)。
- 私有地址 vs 公有地址:
- 图中内网使用的是
10.0.0.0/24网段,这是 RFC 1918 定义的 私有 IP 地址(Private IP)。私有地址在公网(Internet)上是无效的,专门用于局域网。 - 图中的
138.76.29.7是 公有 IP 地址(Public IP)。
- 图中内网使用的是
- NAT 穿越问题 (NAT traversal problem): 外部客户端无法主动连接到 NAT 后的服务器。
- 解决方案 1:静态配置 (Static NAT) (例如端口转发)。
- 解决方案 2:UPnP (Universal Plug and Play) (通用即插即用),允许主机自动配置 NAT 端口映射。
- 解决方案 3:中继 (Relaying) (例如 Skype 使用),两个客户端都连接到一个公共的中继服务器,服务器在两者之间转发数据包。
4.4.3 ICMP:互联网控制消息协议 (ICMP: Internet Control Message Protocol)
IP 协议(网络层)本身是一个“尽力而为”的协议,它只负责把数据包发出去,不保证能送到,也不负责报告错误。ICMP 就是 IP 协议的“辅助/补丁”。
- 功能:它用于在主机和路由器之间传递控制消息。
- 内容:它不传数据,只传“情报”。比如:“网络不通”、“主机关机了”、“路太远走不到了”或者“请把速度放慢点”。
- 封装位置:ICMP 看起来像是一个上层协议(因为它被封装在 IP 数据报里),但在逻辑上它属于网络层 (Layer 3) 的一部分。
- 结构:
[ IP 头部 | ICMP 消息 ]
- 主要用途: 错误报告 (Error reporting) 和 网络查询 (Echo request/reply)。
- ICMP 消息封装在 IP 数据报中。
- 常见类型:
- Type 8 (Echo Request) & Type 0 (Echo Reply):
- 这是 Ping 命令的基础。
- 你发一个 Type 8(请求),对方回一个 Type 0(应答)。如果收到了,说明网络层是通的。
- Type 3 (Destination Unreachable - 目标不可达):
- 当路由器无法找到去往目标的路径,或者目标主机被防火墙拦截时,会返回这个错误。
- 注意:在 Traceroute 的最后一步,正是利用了这个类型(具体是端口不可达)来确认到达终点。
- Type 11 (Time Exceeded - TTL 过期):
- 这是 Traceroute 的核心。
- IP 协议规定,每个数据包都有寿命(TTL)。每经过一个路由器,TTL 减 1。
- 当 TTL 减为 0 时,路由器必须丢弃该包,并向发送者回送一个 Type 11 的 ICMP 消息,告诉发送者:“你的包死在我这里了”。
- Type 8 (Echo Request) & Type 0 (Echo Reply):
- Traceroute 和 ICMP: Traceroute 并不想真的发送数据,它的目的是让沿途的每一个路由器都“报错”,从而暴露它们的身份。
- 探测第一跳 (TTL=1):
- 源主机发送一个 UDP 数据包,目标是最终目的地,端口号选一个很大的随机数(如 33434,确保目标主机上没有程序在用这个端口)。
- 关键点:将 IP 头部的 TTL 设置为 1。
- 结果:数据包到达路径上的第 1 个路由器。路由器将 TTL 减 1 变为 0。路由器丢弃该包,并向源主机发送 ICMP Type 11 (TTL expired)。
- 收获:源主机收到了 ICMP 包,查看其源 IP 地址,就知道了第 1 跳路由器的身份;计算往返时间,就得到了 RTT。
- 探测第二跳 (TTL=2):
- 源主机再次发送 UDP 包,这次将 TTL 设置为 2。
- 过程:
- 第 1 个路由器:
TTL 2 -> 1,转发通过。 - 第 2 个路由器:
TTL 1 -> 0,丢弃!
- 第 1 个路由器:
- 结果:第 2 个路由器向源主机发送 ICMP Type 11。
- 收获:源主机知道了第 2 跳路由器的 IP。
- 循环递增 (TTL=3, 4, 5…):
- Traceroute 程序不断增加 TTL 的值,每次发包都能比上一次多走一步,然后“死”在下一个路由器手里,从而“骗”回下一个路由器的 IP。
- 到达终点 (Stopping Condition):
- 假设目的地在第 跳。源主机发送 TTL= 的包。
- 沿途所有路由器都放行了,数据包顺利到达了目标主机。
- 目标主机不会检查 TTL 是否耗尽(因为它是终点),它试图解包并处理 UDP 数据。
- 关键反转:目标主机发现 UDP 目的端口(如 33434)没有程序在监听。
- 结果:目标主机根据网络协议规定,向源主机发送一个 ICMP Type 3 (Destination Unreachable),具体代码为 Port Unreachable (端口不可达)。
- 结束任务:
- 源主机一直在等 ICMP 消息。之前收到的都是 Type 11 (TTL 过期),意味着还在半路上。
- 一旦收到 Type 3 (端口不可达),源主机就知道:“啊,这是目标主机发回来的,说明我已经到了!”
- 程序停止探测,打印完整路径。
- 探测第一跳 (TTL=1):
4.4.4 IPv6
-
主要动机: 32 位的 IPv4 地址空间已耗尽。
-
IPv6 地址: 128 位。
-
IPv6 数据报格式:
- 固定的 40 字节首部。路由器处理起来非常快,硬件实现更简单。
- 不允许分片 (no fragmentation allowed)(分片只能由源主机在发送前进行)。
- IPv6: 禁止路由器分片。如果包太大(超过链路 MTU),路由器直接丢弃该包,并回送一个 ICMPv6 “Packet Too Big” 消息。
- 处理:源主机收到错误后,必须自己把包切小一点重发(这叫 路径 MTU 发现)。
- Flow Label (流标签): 识别同一“流”中的数据报,有助于 QoS。
- 用于标识属于同一个“流”(Flow)的数据报(例如一个音视频通话的数据流)。
- 这使得路由器可以给特定流提供 QoS (服务质量) 保障,而不需要深度包检测。
-
与 IPv4 的主要变化:
- Checksum (校验和): 彻底移除,以减少每跳的处理时间(依赖链路层和传输层进行校验)。
- 理由:现代链路层(光纤、以太网)非常可靠,很少出错;且传输层(TCP/UDP)本身就有校验。网络层不做重复劳动,以此加快转发速度。
- Options (选项): 允许,但放在首部之外,通过 “Next Header” 字段指示。
- ICMPv6: 新版 ICMP,增加了 “Packet Too Big” 等消息类型。
- Checksum (校验和): 彻底移除,以减少每跳的处理时间(依赖链路层和传输层进行校验)。
-
隧道 (Tunnel):是逻辑上的链路。实际上,它是把 IPv6 数据报当成 IPv4 数据报的 “数据 (Payload)” 来传输。
-
双栈路由器 (Dual-stack Router):隧道两端的路由器(通常是边缘路由器)必须同时支持 IPv4 和 IPv6。
假设:主机 A (IPv6) 想发送数据给 主机 B (IPv6),但中间必须经过一段 IPv4 网络。
- 源主机发送 (IPv6):
- 主机 A 发出一个标准的 IPv6 数据报。
[ IPv6 头部 | 数据 ]- 源地址:A 的 IPv6 地址;目的地址:B 的 IPv6 地址。
- 进入隧道 (Encapsulation / 封装):
- IPv6 数据报到达了“IPv6 岛屿”边缘的路由器(入口节点)。
- 该路由器发现要去往 B,必须经过 IPv4 网络。
- 路由器创建一个 IPv4 数据报。
- 关键操作:它把完整的 IPv6 数据报塞进 IPv4 的“数据部分”。
- IPv4 头部设置:
- 源 IP:入口路由器的 IPv4 地址。
- 目的 IP:出口路由器的 IPv4 地址。
- Protocol 字段:设置为 41 (表示 Payload 是 IPv6)。
- 现在的包结构:
[ IPv4 头部 | IPv6 头部 | 数据 ]
- 穿过隧道 (Transmission):
- 这个包在中间的 IPv4 网络中传输。
- 中间的 IPv4 路由器只看外层的 IPv4 头部。它们根本不知道(也不关心)里面包着一个 IPv6 的包裹。它们只负责把包送到出口路由器的 IPv4 地址。
- 离开隧道 (Decapsulation / 解封装):
- 数据包到达了“IPv6 岛屿”另一端的边缘路由器(出口节点)。
- 出口路由器检查 IPv4 头部,发现 Protocol = 41。
- 它剥离掉外层的 IPv4 头部,取出了里面的 IPv6 数据报。
- 最终交付:
- 出口路由器读取恢复出来的 IPv6 头部(目的地址是 B)。
- 它通过 IPv6 网络将数据报转发给主机 B。