【Linux网络】深入理解网络层协议:IP(一)—— 互联网的基石


🔥草莓熊Lotso: 个人主页
❄️个人专栏: 《C++知识分享》 《Linux 入门到实践:零基础也能懂》
✨生活是默默的坚持,毅力是永久的享受!


🎬 博主简介:


文章目录

  • 前言
  • [一. 预备工作:网络层的基本概念](#一. 预备工作:网络层的基本概念)
    • [1.1 网络层的作用](#1.1 网络层的作用)
    • [1.2 基本术语定义](#1.2 基本术语定义)
    • [1.3 长距离传输的本质](#1.3 长距离传输的本质)
    • [1.4 TCP 与 IP 的关系](#1.4 TCP 与 IP 的关系)
    • [1.5 IP 地址的意义](#1.5 IP 地址的意义)
  • [二. IP 地址:互联网的 "门牌号"](#二. IP 地址:互联网的 "门牌号")
    • [2.1 IP 地址的结构](#2.1 IP 地址的结构)
    • [2.2 唐僧取经的例子](#2.2 唐僧取经的例子)
  • [三. IP 协议格式:报文的 "快递单"](#三. IP 协议格式:报文的 "快递单")
    • [3.1 IP 协议头整体结构](#3.1 IP 协议头整体结构)
    • [3.2 各字段详细解析](#3.2 各字段详细解析)
      • [3.2.1 4 位版本号 (Version)](#3.2.1 4 位版本号 (Version))
      • [3.2.2 4 位首部长度 (Header Length)](#3.2.2 4 位首部长度 (Header Length))
      • [3.2.3 8 位服务类型 (Type Of Service, TOS)](#3.2.3 8 位服务类型 (Type Of Service, TOS))
      • [3.2.4 16 位总长度 (Total Length)](#3.2.4 16 位总长度 (Total Length))
      • [3.2.5 16 位标识 (Identification)](#3.2.5 16 位标识 (Identification))
      • [3.2.6 3 位标志 (Flags)](#3.2.6 3 位标志 (Flags))
      • [3.2.7 13 位片偏移 (Fragment Offset)](#3.2.7 13 位片偏移 (Fragment Offset))
      • [3.2.8 8 位生存时间 (Time To Live, TTL)](#3.2.8 8 位生存时间 (Time To Live, TTL))
      • [3.2.9 8 位协议 (Protocol)](#3.2.9 8 位协议 (Protocol))
      • [3.2.10 16 位首部检验和 (Header Checksum)](#3.2.10 16 位首部检验和 (Header Checksum))
      • [3.2.11 32 位源 IP 地址和目的 IP 地址](#3.2.11 32 位源 IP 地址和目的 IP 地址)
      • [3.2.12 选项字段 (Options)](#3.2.12 选项字段 (Options))
      • [3.2.13 数据部分](#3.2.13 数据部分)
  • [四. 源码解读:Linux 内核 IP 头部结构](#四. 源码解读:Linux 内核 IP 头部结构)
  • 结尾:

前言

之前我们深入讲解了传输层的 TCP 协议,了解了它如何在不可靠的网络之上提供可靠的字节流传输服务。但 TCP 的所有数据最终都要交给网络层的 IP 协议来传输。如果说 TCP 是互联网的 "快递员",负责保证包裹可靠送达,那么 IP 就是互联网的 "导航系统",负责为包裹找到从发送方到接收方的正确路径。IP 协议是整个 TCP/IP 协议栈的核心,也是互联网能够互联互通的基础。本文将从预备知识入手,深入解析 IP 地址的本质和 IP 协议头的每一个字段,结合 Linux 内核源码帮助你彻底理解 IP 协议的工作原理,从容应对各类技术面试。


一. 预备工作:网络层的基本概念

1.1 网络层的作用

网络层(也叫互联网层、网际层)的核心作用是在复杂的网络环境中确定一条从源主机到目的主机的合适路径。传输层负责端到端的可靠传输,而网络层负责点到点的路由转发。

1.2 基本术语定义

  • 主机:配有 IP 地址,也能进行路由控制的设备(比如我们的电脑、手机)
  • 路由器:既配有 IP 地址,又能进行路由控制的设备(是网络中的 "中转站")
  • 节点:主机和路由器的统称

1.3 长距离传输的本质

互联网并不是一个单一的大网络,而是由无数个局域网(子网)通过路由器连接而成的。数据从源主机到目的主机的过程,就是一跳一跳地通过路由器在不同子网之间转发的过程。

举个例子:你在北京的家里给上海的朋友发消息,数据会先从你的电脑发到家里的路由器,然后到小区的路由器,再到运营商的骨干路由器,经过多个路由器转发后,最终到达上海朋友的路由器,再到他的电脑。

1.4 TCP 与 IP 的关系

文档中用了一个非常形象的比喻来解释两者的关系:

  • IP:就像具有数学考满分能力的张三,本身具备把数据从 A 主机跨网络送到 B 主机的能力
  • TCP:就像张三的校长老舅,提供策略保障(确认应答、超时重传、拥塞控制等),确保张三最终一定能考到满分

两者结合,就提供了把数据从 A 主机可靠地跨网络送到 B 主机的能力

1.5 IP 地址的意义

IP 地址是一个 4 字节(32 位)的数字,它的本质作用是提供一种路由查找的能力,就像我们的学号一样。

通过学号找学生的过程:保安大爷(知道学院)→ 扫地阿姨(知道专业和班级)→ 宿管阿姨(知道宿舍) 通过 IP 地址找主机的过程:路由器 A(知道目标网络)→ 路由器 B(知道下一个子网)→ ... → 目标子网的路由器(知道目标主机)

IP 地址之所以能够找到目标主机,是因为它不是一个随机的数字,而是结构化的,包含了目标网络和目标主机两部分信息。


二. IP 地址:互联网的 "门牌号"

2.1 IP 地址的结构

IPv4 地址是一个 32 位的无符号整数,通常采用点分十进制的表示方法(比如 <192.168.1.1>)。它由两部分组成:

  • 网络号:标识主机所在的子网
  • 主机号:标识子网内的具体主机

2.2 唐僧取经的例子

文档中用唐僧取经的例子非常形象地解释了网络号和主机号的作用:

  • 唐僧说:"我从东土大唐来,要去西天面见佛祖求取真经"
  • 路上的所有 "路由器"(各国国王、关卡守卫)只关心 "西天" 这个网络号 ,不关心 "大雷音寺" 这个主机号
  • 等到了西天这个子网,才需要关心 "大雷音寺" 这个具体的主机号

核心结论 :真正支持报文路由转发的是 IP 地址中的网络号,只有到达目标子网后,才会使用主机号找到具体的主机。

三. IP 协议格式:报文的 "快递单"

IP 协议头就像快递单一样,包含了数据传输所需的所有关键信息。理解 IP 协议头的每一个字段,是掌握 IP 协议的关键。

3.1 IP 协议头整体结构

IPv4 协议头的标准长度是 20 字节,如果有选项字段,最长可以达到 60 字节。整体结构如下:

4 位版本 4 位首部长度 8 位服务类型 (TOS) 16 位总长度 (字节数)
16 位标识 3 位标志 13 位片偏移
8 位生存时间 (TTL) 8 位协议 16 位首部检验和
32 位源 IP 地址
32 位目的 IP 地址
选项 (最多 40 字节)
数据 (有效载荷)

3.2 各字段详细解析

3.2.1 4 位版本号 (Version)

指定 IP 协议的版本,对于 IPv4 来说,这个字段的值是 4;对于 IPv6 来说,这个字段的值是 6。

注意:IPv4 和 IPv6 是两个完全不兼容的协议,IPv6 使用 128 位地址,理论上可以解决 IPv4 地址不足的问题,但目前主流仍然是 IPv4。

3.2.2 4 位首部长度 (Header Length)

表示 IP 头部的长度,单位是32 位字(4 字节)。因为 4 位最大能表示 15,所以 IP 头部的最大长度是 15×4=60 字节。

  • 没有选项的标准 IP 头部:首部长度 = 5(5×4=20 字节)
  • 有选项的 IP 头部:首部长度 > 5,最大为 15

这个字段的作用是让接收方能够正确地分离 IP 头部和有效载荷:

Plain 复制代码
有效载荷长度 = 总长度 - 首部长度×4

3.2.3 8 位服务类型 (Type Of Service, TOS)

这个字段用于指定 IP 报文的传输优先级和服务质量。它由三部分组成:

  • 3 位优先权字段:已经弃用
  • 4 位 TOS 字段:分别表示最小延时、最大吞吐量、最高可靠性、最小成本
  • 1 位保留字段:必须置为 0

重要特性:这四个 TOS 选项是相互冲突的,只能选择一个。

  • SSH/Telnet 等交互式应用:选择最小延时
  • FTP 等文件传输应用:选择最大吞吐量

不同的服务类型会影响路由器选择的转发路径。

3.2.4 16 位总长度 (Total Length)

表示整个 IP 数据报(头部 + 数据)的总长度,单位是字节。因为是 16 位,所以 IP 数据报的最大长度是 65535 字节。

3.2.5 16 位标识 (Identification)

唯一标识主机发送的每一个 IP 报文。如果 IP 报文在数据链路层被分片了,那么同一个原始报文的所有分片的这个标识字段都是相同的。

接收方通过这个字段来判断哪些分片属于同一个原始报文,从而进行重组。

3.2.6 3 位标志 (Flags)

这个字段用于控制 IP 报文的分片:

  • 第 1 位:保留位,现在不用
  • 第 2 位:禁止分片位 (DF),如果置为 1,表示禁止分片。如果报文长度超过 MTU(最大传输单元),IP 模块会直接丢弃这个报文
  • 第 3 位:更多分片位 (MF),如果置为 1,表示后面还有更多的分片;如果置为 0,表示这是最后一个分片

3.2.7 13 位片偏移 (Fragment Offset)

表示当前分片相对于原始 IP 报文数据部分的偏移量。实际偏移的字节数是这个值乘以 8

例如:片偏移 = 100,表示这个分片的数据从原始报文的第 800 字节开始。

重要特性:除了最后一个分片之外,其他所有分片的长度都必须是 8 的整数倍,这样才能保证偏移量是整数。

3.2.8 8 位生存时间 (Time To Live, TTL)

表示 IP 报文在网络中能够存活的最大跳数。

  • 初始值一般是 64(不同操作系统可能不同)
  • 每经过一个路由器,TTL 的值减 1
  • 当 TTL 减到 0 时,路由器会丢弃这个报文,并向源主机发送 ICMP 超时错误报文

核心作用防止路由循环。如果网络中出现了路由环路,报文会在环路中无限转发,消耗大量网络资源。TTL 机制保证了报文最终会被丢弃。

我们平时使用的ping命令就可以看到 TTL 的值:

Plain 复制代码
C:\Users\whb>ping www.baidu.com
正在Ping www.a.shifen.com[183.2.172.177]具有32字节的数据:
来自183.2.172.177的回复:字节=32时间=35msTTL=52

这里的 TTL=52 表示这个报文从百度服务器到我们的电脑经过了 64-52=12 个路由器。

3.2.9 8 位协议 (Protocol)

表示 IP 报文的有效载荷是哪种上层协议的数据。接收方通过这个字段来决定将有效载荷交给哪个上层协议处理。

常见的协议号如下:

协议号 协议类型 全称与说明
1 ICMP 互联网控制报文协议,用于发送错误报告和网络诊断(如 ping 命令)
2 IGMP 互联网组管理协议,用于管理 IP 多播组成员
6 TCP 传输控制协议,提供面向连接的可靠数据传输服务
17 UDP 用户数据报协议,提供无连接的不可靠数据传输服务
47 GRE 通用路由封装,用于封装其他网络协议,常被 VPN 使用
50 ESP 封装安全载荷,IPSec 协议的一部分,用于数据加密和认证
51 AH 认证头,IPSec 协议的一部分,用于数据完整性校验和身份认证
89 OSPF 开放最短路径优先,一种内部网关路由协议

3.2.10 16 位首部检验和 (Header Checksum)

用于校验 IP 头部是否在传输过程中损坏。发送方计算 IP 头部的 CRC 校验和并填入这个字段,接收方重新计算校验和,如果和收到的不一致,就丢弃这个报文。

注意:这个校验和只校验 IP 头部,不校验数据部分。数据部分的校验由上层协议(TCP/UDP)负责。

3.2.11 32 位源 IP 地址和目的 IP 地址

分别表示发送方和接收方的 IP 地址,是 IP 报文最重要的字段之一。

3.2.12 选项字段 (Options)

可选字段,最长 40 字节,用于提供一些额外的功能,比如记录路由、时间戳、安全选项等。大多数情况下,这个字段为空。

3.2.13 数据部分

IP 报文的有效载荷,通常是 TCP 段、UDP 数据报或者 ICMP 报文等上层协议的数据。


四. 源码解读:Linux 内核 IP 头部结构

我们来看一下 Linux 内核中 IP 头部的定义(位于include/linux/ip.h):

c 复制代码
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,      // 首部长度(Internet Header Length)
            version:4;  // 版本号
#elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,  // 版本号
            ihl:4;      // 首部长度
#else
#error  "Please fix <asm/byteorder.h>"
#endif
    __u8    tos;        // 服务类型(Type Of Service)
    __be16  tot_len;    // 总长度(Total Length)
    __be16  id;         // 标识(Identification)
    __be16  frag_off;   // 标志(3位)+片偏移(13位)
    __u8    ttl;        // 生存时间(Time To Live)
    __u8    protocol;   // 上层协议类型
    __be16  check;      // 首部校验和
    __be32  saddr;      // 源IP地址
    __be32  daddr;      // 目的IP地址
    /* 选项字段从这里开始 */
};

关键字段对应解读

  • version:对应 4 位版本号字段
  • ihl:对应 4 位首部长度字段,单位是 4 字节
  • tos:对应 8 位服务类型字段
  • tot_len:对应 16 位总长度字段
  • id:对应 16 位标识字段
  • frag_off:高 3 位是标志字段,低 13 位是片偏移字段
  • ttl:对应 8 位生存时间字段
  • protocol:对应 8 位协议字段
  • check:对应 16 位首部校验和字段
  • saddr:对应 32 位源 IP 地址字段
  • daddr:对应 32 位目的 IP 地址字段

注意这里的字节序问题:Linux 内核使用了条件编译来处理大端和小端字节序的差异,保证在不同架构的 CPU 上都能正确解析 IP 头部。

核心考点总结

  1. 网络层的核心作用是路由转发,长距离传输的本质是子网间的一跳一跳转发
  2. TCP 与 IP 的关系:IP 提供基础传输能力,TCP 提供端到端的可靠性保障
  3. IP 地址的结构化设计:网络号用于跨子网路由,主机号用于子网内寻址
  4. IP 协议头各字段的作用,特别是 TTL、协议号、首部长度和分片相关字段
  5. TTL 的核心作用是防止路由循环,每经过一个路由器值减 1
  6. 8 位协议字段的常见值(TCP=6,UDP=17,ICMP=1)
  7. IP 分片机制的原理:标识、标志、片偏移三个字段的协同工作

结尾:

html 复制代码
🍓 我是草莓熊 Lotso!若这篇技术干货帮你打通了学习中的卡点:
👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长
❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量
⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用
💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑
🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解
技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标!

结语:本文详细讲解了网络层 IP 协议的基础概念、IP 地址的本质以及 IP 协议头的每一个字段。IP 协议作为互联网的基石,其设计简洁而精妙,每一个字段都有其特定的作用。在下一篇文章中,我们将继续深入讲解 IP 协议的高级特性,包括 IP 分片与重组、NAT 网络地址转换、路由表与路由转发原理等内容,敬请期待。

✨把这些内容吃透超牛的!放松下吧✨ ʕ˘ᴥ˘ʔ づきらど