网络层
网络层通常又称为网际层(internet layer)或IP层。网络层向上只提供简单灵活的、无连接的、尽最大努力交付的数据报服务。其所传输的单元称为IP数据报(IP datagram)或分组,网络层本身不对服务质量作出任何保证,即所传送的分组可能出现差错、丢失、重复与失序(即不按顺序抵达终点),同时也不承诺交付时限。正因为如此,网络的造价得以显著降低,运行机制更为灵活,能够适配各类应用场景。
网际协议IP
网际协议IP又称为Kahn-Cerf协议(因为其研发者是Robert Kahn和Vint Cerf),是TCP/IP体系中两个最主要的协议之一,当前主要使用的是IP协议的第4个版本,记为IPv4,IP协议通常与以下三个协议配套使用:
- 地址解析协议 ARP(Address Resolution Protocol)
- 网际控制报文协议ICMP(Internet Control Message Protocol)
- 网际管理协议IGMP(Internet Group Management Protocol)
IP层解决的问题(虚拟互联网络)
世界范围内的计算机网络千差万别,它们有不同的编址方案、不同的最大分组长度、不同的差错恢复机制等等,网络与网络之间相互连接,需要依赖中间设备,根据所在层次不同,中间设备分为四类:
- 物理层使用的中间设备称为转发器
- 数据链路层使用的中间设备称为网桥或桥接器
- 网络层使用的中间设备称为路由器,早期的RFC文档则将它们称为网关
- 网络层以上使用的中间设备称为网关,用网关连接两个不兼容的系统时,需要在高层进行协议转换
当这些异构网络通过路由器互连起来时,如果所有的网络都使用相同的IP协议,这些网络中的主机就好像在一个单个网络上通信一样,不需要管互连的各网络的具体异构细节,即它们形成了一个虚拟互联网络,称为IP网。这里的”虚拟”,是指底层各种物理网络的异构性客观存在,但IP协议将其屏蔽,使得从网络层往上看,这些差异各异的网络仿佛是一个统一的整体。
IPv4地址
IP协议将整个的互联网抽象为了一个单一的网络,因此IP地址是用来给互联网上的每一台主机(或路由器)的每一个接口分配的一个在全世界范围内是唯一的寻址地址,IP地址现在由ICANN组织旗下的IANA小组负责分配。IP地址有以下特点:
- IP地址都由网络号和主机号组成
- IP地址标识的是一台主机(或路由器)与一条链路之间的接口,当主机连接到多个网络时,就要拥有对应的多个IP地址,这类主机称为多归属主机(multihomed host)。由于一个路由器至少连接两个网络,因此一个路由器至少拥有两个不同的IP地址。
- 拥有相同网络号的主机同属于一个网络,因此,用转发器、网桥、交换机连接起来的多个局域网也同属于一个网络。
- 两个路由器直接相连时,连线两端的接口可以分配IP地址,也可以不分配,不分配IP地址时,这对接口之间只有一条线路的特殊网络称为无名网络(anonymous network)或无编号网络(unnumbered network)
IPv4地址的组成
IP地址是一组32位的二进制代码,因此总共有232个IP地址(大约40亿个)。为了提高可读性,通常使用点分十进制表示,即每8位插入一个点号,并用其等效的十进制数字表示,范围为0.0.0.0-255.255.255.255,以下是一些日常常用的IP地址:
DNS服务
- 1.1.1.1 Cloudflare公共DNS,主打隐私保护,承诺不记录用户查询日志,解析速度快,备用地址:1.0.0.1
- 8.8.8.8 Google公共DNS,速度快,稳定,备用地址:8.8.4.4
- 9.9.9.9 IBM公共DNS
- 114.114.114.114 国内老牌公共DNS,兼容性极佳
- 223.5.5.5 阿里云公共DNS,国内主流选择
- 119.29.29.29 腾讯DNS,针对腾讯系主流网站、游戏和视频平台有优化
- 180.76.76.76 百度公共DNS,对百度系产品(搜索、网盘)有专项优化
特殊地址
- 127.x.x.x 本地环回地址(Localhost)
- 0.0.0.0 默认路由/任意地址,在路由表中表示默认网关;在防火墙、web监听等服务中表示所有IPv4地址
- 255.255.255.255 受限广播地址,向当前广播域内的所有主机发送数据包
- 10.x.x.x A类私有地址,用于企业内部大型网络
- 172.16.x.x - 172.31.x.x B类私有地址,用于中型网络
- 192.168.x.x C类私有地址,最常见的家庭/小型办公网络地址
- 169.254.x.x 自动专用IP地址(APIPA),主机未找到DHCP服务器自行分配的地址,通常意味着网络故障或网线没插好
具有特殊用途的IP地址
这些地址通常用于特殊领域,在公网上不可路由(多播地址除外)
- 本地环回(Loopback)地址:127.0.0.0 – 127.255.255.255(127.0.0.0/8),发往该地址的数据包不经过网卡,直接在主机内部协议栈中“回转”,常用于本地系统自检
- 链路本地(Link-Local)地址:169.254.0.0 – 169.254.255.255(169.254.0.0/16),当DHCP服务器失效时,操作系统会自动为自己分配一个 169.254.x.x 的地址,仅用于本地链路内的临时通信,无法被路由
- A类中的本网络地址:0.0.0.0 – 0.255.255.255(0.0.0.0/8),早年在A类地址中用于表示本网络,现作为历史遗留保留,不再使用
- 私有地址:早年ABC类地址中被保留的私有地址,常用于局域网环境,它们不由ICANA直接分配,而是由路由器在家庭、公司等局域网(LAN)环境下分配使用,这些地址在公网上是不可路由的:
- A类10.0.0.0 – 10.255.255.255(10.0.0.0/8)
- B类172.16.0.0 – 172.31.255.255(172.16.0.0/12)
- C类192.168.0.0 – 192.168.255.255(192.168.0.0/16)
- 文档示例地址:RFC规定为文档和示例代码保留的地址块,它们不可路由,唯一的使命就是被写进技术文档、教程或产品手册里当例子:
- TEST-NET-1:192.0.2.0 – 192.0.2.255(192.0.2.0/24)
- TEST-NET-2:198.51.100.0 – 198.51.100.255(198.51.100.0/24)
- TEST-NET-3:203.0.113.0 – 203.0.113.255(203.0.113.0/24)
- 运营商NAT:100.64.0.0 – 100.127.255.255(100.64.0.0/10),用于CGNAT(运营商级 NAT),运营商可以将该网段IP地址同时分配给不同区域的用户使用,以解决IP地址池不够用的问题。由于需要NAT,该环境下的用户可能遇到无法从外网直接访问家中的NAS、监控摄像等常见的内网环境问题。
- IANA保留:192.0.0.0 – 192.0.0.255,IANA保留,交给IETF(制作互联网核心技术标准的组织)用于测试新协议,或者按需分配给未来的新协议
- IPv6过渡技术专用地址:192.88.99.0 – 192.88.99.255(192.88.99.0/24),曾是IPv6过渡技术6to4的中继任播前缀,但目前已被正式弃用。6to4 是一种隧道技术,允许那些还没有原生IPv6网络的站点,将IPv6数据包封装在 IPv4中,穿越IPv4网络进行传输。实际上,该网段中的IP地址只有192.88.99.1作为任播地址被使用,其余地址被保留但未被使用,当一个6to4用户需要与IPv6网络通信时,用户端可以直接将数据包发往192.88.99.1而不需要查询
- 设备性能测试地址:198.18.0.0 – 198.19.255.255(198.18.0.0/15),用于实验室环境下,测试网络设备的基准性能
- 多播:224.0.0.0 – 239.255.255.255(224.0.0.0/4),用于多播,D类地址
- 保留未来使用:240.0.0.0 – 255.255.255.254(240.0.0.0/4),E类地址
- 受限广播地址:255.255.255.255,用于在当前网络内广播,路由器会隔离广播域,绝不允许分组跨过路由器(网关)转发,常用于DHCP服务
完整的IP地址分配表
| 地址范围 | CIDR表示 | 用途 |
|---|---|---|
| 0.0.0.0 – 0.255.255.255 | 0.0.0.0/8 | 不能用于分配,网络号全0早年在A类地址中用于表示本网络,现作为历史遗留保留 |
| 1.0.0.0 – 9.255.255.255 | 公网块,包含多个地址块 | 公网可分配 |
| 10.0.0.0 – 10.255.255.255 | 10.0.0.0/8 | A类地址中的私有地址,不能被分配 |
| 11.0.0.0 – 99.255.255.255 | 公网块 | 公网可分配 |
| 100.0.0.0 – 100.63.255.255 | 公网块 | 公网可分配,但该块中100.64.0.0/10被保留 |
| 100.64.0.0 – 100.127.255.255 | 100.64.0.0/10 | 被保留,用于CGNAT(运营商级 NAT),运营商可以将该网段同时分配给多个不同区域的用户使用 |
| 100.128.0.0 – 126.255.255.255 | 多个地址块 | 公网可分配 |
| 127.0.0.0 – 127.255.255.255 | 127.0.0.0/8 | 本地环回(Loopback)地址 |
| 128.0.0.0 – 169.253.255.255 | 公网块 | 公网可分配 |
| 169.254.0.0 – 169.254.255.255 | 169.254.0.0/16 | 链路本地地址(APIPA),当DHCP服务器失效时,操作系统会自动为自己分配一个 169.254.x.x 的地址,方便与同网络内主机通信 |
| 169.255.0.0 – 172.15.255.255 | 公网块 | 公网可分配 |
| 172.16.0.0 – 172.31.255.255 | 172.16.0.0/12 | B类地址中的私有地址,不能被分配 |
| 172.32.0.0 – 191.255.255.255 | 公网块 | 公网可分配 |
| 192.0.0.0 – 192.0.0.255 | 保留段 | IANA保留,用于未来的创新协议 |
| 192.0.2.0 – 192.0.2.255 | 192.0.2.0/24 | 用于技术文档、手册示例(TEST-NET-1) |
| 192.0.3.0 – 192.88.98.255 | 公网块 | 公网可分配 |
| 192.88.99.0 – 192.88.99.255 | 192.88.99.0/24 | 曾用于IPv6过渡技术6to4的隧道技术,已弃用 |
| 192.89.0.0 – 192.167.255.255 | 公网块 | 公网可分配 |
| 192.168.0.0 – 192.168.255.255 | 192.168.0.0/16 | C类地址中保留的私有地址,不能被分配 |
| 192.169.0.0 – 198.17.255.255 | 公网块 | 公网可分配 |
| 198.18.0.0 – 198.19.255.255 | 198.18.0.0/15 | 用于网络设备性能测试 |
| 198.20.0.0 – 198.51.99.255 | 公网块 | 公网可分配 |
| 198.51.100.0 – 198.51.100.255 | 198.51.100.0/24 | 用于技术文档、手册示例(TEST-NET-2) |
| 198.51.101.0 – 203.0.112.255 | 公网块 | 公网可分配 |
| 203.0.113.0 – 203.0.113.255 | 203.0.113.0/24 | 用于技术文档、手册示例(TEST-NET-3) |
| 203.0.114.0 – 223.255.255.255 | 公网块 | 公网可分配,C类地址的大规模公网空间 |
| 224.0.0.0 – 239.255.255.255 | 224.0.0.0/4 | 用于多播,D类地址 |
| 240.0.0.0 – 255.255.255.254 | 240.0.0.0/4 | 未来保留,用于实验等领域,E类地址 |
| 255.255.255.255 | 无 | 受限广播,用于在当前网络内广播 |
IPv4地址的早期分类
IP地址的分类概念源于互联网早期发展阶段,随着无类别域间路由技术的普及,这种分类方法已经不再主流使用。
早期分类方法把IP地址划分为A、B、C、D、E五大类,称为”有类编址”,其中A、B、C类地址都由两个固定长度的字段组成,第一个字段是网络号(net-id),网络字段的前1-3位为类别位,用于区别ABC的类别;第二个字段是主机号(host-id),它们都是单播地址。D类地址用于多播通信,E类地址保留为以后使用。

A类地址
- A类地址网络号字段占用1字节(默认子网掩码为255.0.0.0),最高位固定为0(作为它的类别位),数值范围从1到126。由于类别位占用了1位,因此可指派的网络号是126个(即27-2),减2是因为有两个保留地址:
- 网络号全为0的IP地址用于表示本网络,如:0.10.20.30表示本网络上的主机10.20.30,但由于“本网络”的解释依赖于当前网络上下文,无法被跨设备解释,也无法被路由,因此0.x.x.x仅作为历史保留的地址,不会实际分配。其中,全0的IP地址0.0.0.0用于表示当前网络中的当前主机(RFC术语“this host on this network”,工程语义为“当前主机,但我还不知道自己的IP”),常用于DHCP协议中,新主机将其填入源IP地址作为占位符,以表示“我是这个网络上的一台主机,但我还没有地址”。在操作系统/防火墙中,该IP地址被扩展用来表示所有IP,但这不是IP协议定义的含义。
- 网络号127(即01111111)用于环回测试(loopback test),如:若主机发送一个目的地址为127.0.0.1的IP数据报,则本主机中的协议软件将处理这些数据,而不会把数据报发送到任何网络。
- A类地址的主机号占3个字节,因此每一个A类网络中的最大主机数是224-2,即16777214。这里减2的原因是:
- 全0的主机号用于表示该IP地址所属的网络地址,即用于标识该网络本身(如:若一主机的IP地址为5.6.7.8,则该主机所在的网络地址就是5.0.0.0,IP地址5.0.0.0表示网络号为5的网络本身)
- 全1的主机号用于表示该网络上的广播地址(Broadcast Address),表示该网络上的”所有主机”,(如:5.255.255.255表示网络5.0.0.0上的所有主机)
B类地址
- B类地址的网络号字段占用2个字节,前面两位10固定,剩余14位可以进行分配。由于类别位为10,因此无法出现网络号全0或全1,因此这里不存在网络总数减2的问题。但由于128.0.0.0表示B类网络地址本身,因此可以指派的B类最小网络地址是128.1.0.0。因此B类地址可指派的网络数为214-1,即16383
- B类地址每个网络上的最大主机数是216-2,即65534。这里需要减2是因为要扣除全0和全1的主机号
C类地址
- C类地址有3个字节的网络号字段,最前面的3位是(110),还有21位可以进行分配。C类网络地址192.0.0.0也是不指派的,可以指派的C类最小网络地址是192.0.1.0,因此C类地址可指派的网络总数是221-1,即2097151
- 每一个C类地址的最大主机数是28-2,即254,同样扣除全0和全1的主机号
D类和E类地址
D类和E类地址都不分配给普通用户作为设备地址,它们有各自的专业用途:
D类地址的范围为224.0.0.0 至 239.255.255.255,用于一对多的组播通信,专门向网络中特定的一组主机发送信息,而不是单一主机或所有主机,通常用于在线视频会议、网络直播、IPTV、动态路由协议(如OSPF)等
E类地址的范围为240.0.0.0 至 255.255.255.254,它们作为保留地址,在公网上不可路由,仅用于科学实验、未来网络技术研究与开发测试
1. IP地址空间利用率低,A类地址可连接的主机数超过1000万,B类地址网络可连接的主机数超过6万,如果一个单位申请到了一个B类地址网络,但所连接的主机数并不多,将造成极大的IP浪费
2. 给每个物理网络分配独立网络号,会导致路由表中的项目数急剧膨胀,这会极大地增大路由查找时耗
3. 两级IP地址结构僵化,不够灵活。如果一个单位要增加新的网络,则需要申请新的网络号,缺乏按需扩展的灵活性
划分子网
划分子网(subneting)是指在原有的ABC分类基础上,从主机号中划分若干位作为子网号(subnet-id),将IP地址从{网络号,主机号}两级结构拆分为{网络号,子网号,主机号}三级结构。凡是从其他网络发送给本单位某台主机的IP数据报,仍然是根据IP 数据报的目的网络号找到连接在本单位网络上的路由器。但此路由器在收到IP数据报后,再按目的网络号和子网号找到目的子网,把IP数据报交付目的主机,整个网络对外部仍表现为一个网络。
子网掩码
由于IP地址本身以及数据报的首部都没有包含任何有关子网划分的信息,因此路由器仅凭IP地址或首部无法将IP数据报正确交付目的子网,因此,路由器必须依赖一个额外的、且与本地接口强绑定的参数来执行网络前缀的边界判定,这个参数便是子网掩码(subnet mask)。
子网掩码的本质是一段与IP地址按位对应的二进制序列,用来帮助设备明确区分IP地址的“网络部分”和“主机部分”。它的编写遵循严格的结构规则:从高位到低位必须是连续的“1”之后紧跟连续的“0”,且中间不能出现交错或断裂(RFC文档没有规定1或0一定要连续,但极力推荐连续以避免意料之外的错误)。主机或路由器只需要按位与(AND),就能够稳定且唯一地提取出网络地址。
| IP地址 | 141 | 14 | 01001000 | 24 |
|---|---|---|---|---|
| 子网掩码 | 255 | 255 | 11000000 | 0 |
| 按位与结果 | 141 | 14 | 01000000 | 0 |
| 网络地址 | 141 | 14 | 64 | 0 |
无分类编址CIDR(构造超网)
无分类域间路由选择CIDR(Classless Inter-Domain Routing,发音为“sider”)消除了传统的A类、B类和C类地址以及划分子网的概念,不再限制网络号位数,从而更加高效地分配IPv4地址:
- 使用网络前缀(network-prefix)来指明网络,其余部分用来指明主机号,IP地址通过{网络前缀,主机号}两级结构表示
- 使用斜线记法(slash notation,又称为CIDR记法)来表示网络前缀所占的位数,如:128.14.35.7/20
- 具有相同网络前缀的连续IP同属一个CIDR地址块,只需要知道该地址块的任意一个地址,就可以知道该地址块的最小地址(主机位全0)和最大地址(主机位全1),但这两个地址一般不分配使用。通常使用最小地址(主机位全0)和网络前缀位数指明该地址块,如:下述地址块可以记为128.14.32.0/20。
- 一个CIDR地址块通常包含多个旧的B类或C类地址,因此CIDR又称为构造超网,旧分类方式中,多个C类地址需要对应的多个路由项,但现在这些连续的网络地址块合并为一条超网路由条目进行宣告(称为地址聚合),极大地缩短了路由表的规模,加快了路由匹配速度
- CIDR记法还有其他表示方式:
- 将点分十进制中低位连续的0省略,如:10.0.0.0/10可简写为10/10
- 在网络前缀的后面加一个星号*,以表示主机号任意,如:00001010 00*
- 为方便路由,CIDR依旧使用32位地址掩码(address mask,也可以继续称为子网掩码),斜线记法中斜线后的数字就是地址掩码中1的个数
- 虽然CIDR不再使用分类和子网的概念,但分配到一个CIDR地址块的单位依旧可以自行分配子网,只需要子网的网络前缀比分到的CIDR块网络前缀长度长
IPv4数据报
在TCP/IP的标准中,各种数据格式常常以32位(即4字节)为单位来描述。一个IP数据报由首部和数据两部分组成。首部的前一部分是固定长度,共20字节,是所有IP数据报必须具有的。在首部的固定部分的后面是一些可选字段,其长度是可变的。

- 版本:IP协议的版本,占4位,通信双方使用的版本必须一致。目前广泛使用的IP协议版本号为4(IPv4)和6(IPv6)
- 首部长度:占4位,最大可表示值为15,单位为4字节,这是因为首部长度字段以4字节(32位字)作为计量单位,这意味着如果首部长度值为n,则表示首部长度为4n字节。因为IP首部的固定长度是20字节,因此首部长度字段的最小值是5。当IP分组的首部长度不是4字节的整数倍时,必须利用最后的填充字段加以填充。因此IP数据报的数据部分永远在4字节的整数倍时开始
- 区分服务:占8位,旧标准中叫做服务类型ToS(Type of Service),包含3位优先级,3个标志位(D 延迟、T 吞吐量、R 可靠性),2位保留。但这些字段一直未被使用,后被改名为区分服务DS(DifferentiatedServices),用于在带宽有限、发生拥塞时,优先保证重要流量(如视频会议、VoIP)的传输,而牺牲非关键流量(如P2P下载),字段分为6位的DSCP(区分服务码点)和2位的ECN(显式拥塞通知),通常只有使用区分服务时才使用该字段,大多数情况下并不使用
- 总长度:首部和数据长度之和,单位为字节,占用16位,因此数据报的最大长度为65535字节,但由于链路层限制,通常达不到该值。这是因为,每种数据链路层协议都规定了其数据帧的最大长度,即最大传送单元MTU(Maximum Transfer Unit),IP数据报的总长度(首部+数据)不能超过下层数据链路层的MTU值。例如,以太网的MTU为1500字节。若数据报超过MTU,则需分片处理。此外,分组在计算机网络中传输时,需要经过各种网络设备,它们的性能参差不齐,每种网络设备所能处理的帧长度也参差不齐,为此,IP协议规定,所有主机和路由器必须能接收长度不超过576字节的数据报(由512字节数据、最长60字节首部及4字节富余量得出)。若需发送更长的数据报,应先确认目的主机是否支持,否则需进行分片,因此主机所发送的数据报,在主机已经进行分片后,在某个结点可能会因为路由器性能问题,再次被分片为多个。因此,分片后,“总长度”字段指的是每个分片的首部长度与该分片数据长度的总和
- 标识(identification):占16位。这是一个计数器,每产生一个数据报,计数器就加1,被分片的数据报会有相同的标识值,即当数据报由于长度超过网络的MTU而必须分片时,这个标识字段的值会被复制到所有的数据报片的标识字段中。相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报
- 标志(flag):占3位,但目前只有两位有意义:
- 标志字段中的最低位记为MF(More Fragment)。MF=1 即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个。
- 标志字段中间的一位记为DF(Don’t Fragment),意思是“不能分片”。只有当DF=0时才允许分片。
- 片偏移:占13位,当较长的分组在被分片后,片偏移用于指出某片在原分组中的相对位置。也就是说,相对于用户数据字段的起点。片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍。
| 数据报片 | 总长度 | 标识 | MF | DF | 片偏移 |
|---|---|---|---|---|---|
| 片1 | 1420 | 112 | 1 | 0 | 0 |
| 片2 | 1420 | 112 | 1 | 0 | 175 |
| 片3 | 1020 | 112 | 0 | 0 | 350 |
- 生存时间TTL(Time ToLive):占8位,指定数据报在网络中的寿命。其目的是防止数据报在互联网中因路由环路而无限循环传输(如从路由器R1转发到R2,再转发到R3,然后又转发到R1),浪费互联网资源。早期使用秒作为TTL值的单位,随着技术进步,路由器处理数据报的时间很短,因此现在转而使用路由器跳数作为计量单位,路由器在每次转发数据报之前就把TTL值减1。若TTL值减小到零,就丢弃这个数据报,不再转发。因此,数据报能在互联网中经过的路由器的最大数值是255(因为占用8位),若把TTL的初始值设置为1,就表示这个数据报只能在本局域网中传送
- 协议:占8位,协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个协议进行处理,以下是常用协议及其字段值:
| 协议 | ICMP | IGMP | IP | TCP | EGP | IGP | UDP | IPv6 | ESP | OSPF |
|---|---|---|---|---|---|---|---|---|---|---|
| 协议值 | 1 | 2 | 4 | 6 | 8 | 9 | 17 | 41 | 50 | 89 |
- 首部检验和:占用16位,IP层只检验数据报的首部,不校验数据部分,这是因为数据报每经过一个路由器,数据报的某些字段(如生存时间、标志、片偏移等都可能发生变化),因此路由器既要重新生成首部检验和,也要进行检验和计算,不检验数据部分可减少计算的工作量。IP首部的检验和计算方式类似于运输层,但不会添加伪首部:
- 发送方把IP数据报首部分割为16位字的序列,并把检验和字段置零
- 对这些16位二进制数求和,如果高位有溢出,需要将结果回卷到低位,如果回卷还有溢出,继续加回到低位(循环该步骤)
- 对最终结果取反,填入检验和字段
- 对接收方,将包括检验和在内的所有二进制数相加,结果应该为全1,如果任意比特为0,说明分组出错,应当丢弃该报文
- 源IP地址:占用32位
- 目的IP地址:占用32位
- 选项:用来支持排错、测量以及安全等措施,长度可变(从1个字节到40个字节不等),有多个选项时直接一个个拼接起来,中间不需要有分隔符,最后用全0的填充字段补齐成为4字节的整数倍。增加首部的可变部分是为了增加IP 数据报的功能,但这同时也使得IP数据报的首部长度成为可变的。这就增加了每一个路由器处理数据报的开销。实际上这些选项很少被使用。很多路由器都不考虑IP首部的选项字段,因此新的IP版本IPv6就把IP数据报的首部长度做成固定的。
IPv6
随着IPv4地址池的耗尽,具有更大地址空间IPv6开始推广使用(历史上人们曾设想ST-2协议会成为IPv5,但后来ST-2协议被弃用了),IPv6有以下特点:
- 使用128位地址长度,理论地址数量为2128(约340万亿亿亿个),这意味着地球上的每粒沙子都可以分配到6660亿个IP地址,因此不再需要NAT了
- 支持即插即用(SLAAC,无状态自动配置),设备接入网络后,可结合路由器通告和自身MAC地址自动生成全球唯一的公网IP,不再需要DHCP
- IPv6支持单播(unicast,一对一通信)、多播(multocast,一对多通信,数据报发送到一组计算机中的每一个,IPv6没有采用广播的术语,而是将广播看作多播的一个特例)、任播(Pv6新增的类型,任播的终点是一组计算机,但数据报只交付其中的一个,通常是距离最近的一个)
- Pv6把实现IPv6的主机和路由器均称为结点,IP地址被分配给结点的接口,结点连接了多个不同网络时,一个结点可以有多个单播地址
- IPv6基本首部大小固定为40字节,扩展选项放在有效载荷中(基本首部之后),路由器只需处理大小固定的基本首部,以及偶尔出现的逐跳扩展首部,因此有更高的处理效率。剩余扩展选项只在路径两端的源主机和目的主机中处理,不添加路由器负担
- IPv6首部改为8字节对齐,以适应现代计算机普遍64位的处理器架构,优化处理效率。固定首部长40字节已经是8字节的整数倍,无需填充,扩展首部长度不满足对齐要求时,需要通过填充垫片(Pad1/PadN)补齐
- IPv6允许协议继续扩充,技术不断发展,未来可能出现新的协议,IPv6允许未来定义全新的扩展首部,无需修改现有的IPv6基本首部格式,也不会导致旧设备无法处理新功能的数据包,而IPv4的功能固定不变没有该优点
IPv6地址
IPv6地址长128位,使用冒分十六进制表示方式:
- 每16位为一组,一共8组,每组使用4个十六进制数表示,各组之间冒号分隔,如2001:0db8:85a3:0000:0000:8a2e:0370:7334
- 前导的零允许省略,如:0db8:写为:db8:,FFFF:0000:FFFF写为FFFF:0:FFFF,但至少保留一个0,否则FFFF::FFFF会解析为零压缩
- 连续的零可以使用一对冒号替代,称为零压缩,如FF05:0:0:0:0:0:0:B3压缩为FF05::B3,该地址会自行扩充为8组且全补0,但一个地址中只能使用一次,因为如果使用多次,主机无法知道哪个位置扩充几组0
- 支持以x:x:x:x:x:x:d.d.d.d(6组IPv6,4组IPv4)形式结合使用点分十进制作为后缀(只能放在末尾),如0:0:0:0:0:0:128.10.2.1或零压缩为::128.10.2.1,点分十进制部分每组依旧只表示一个字节,前6组IPv6格式占用96位,后4组IPv4格式占用32位,常用于IPv4向IPv6转换阶段
IPv6地址分类
- 未指明地址:::/128,地址全0,可缩写为两个冒号,这个地址不能用作目的地址,而只能在某主机未得到IP地址时,作为源地址使用
- 环回地址:0:0:0:0:0:0:0:1,缩写为::1,它的作用和IPv4的环回地址一样
- 多播地址:FF00::/8,前8位为1,用于多播,这类地址占IPv6地址总数的1/256
- 本地链路单播地址(Link-Local Unicast Address):FE80::/10,前10位为1111111010,只用于本地通信,不能和互联网上的其他主机通信,用于不需要连接互联网的局域网内部通信,这类地址占IPv6地址总数的1/1024
- 全球单播地址:除上述地址以外的所有地址,用于IPv6全球寻址,单播通信。它可以有多种划分方案,比如选取前n位为子网前缀,剩余128-n位作为主机接口标识;或者选取n位全球路由前缀,m位子网标识,128-n-m位主机接口标识等
IPv6数据报
IPv6数据报由基本首部(base header)和有效载荷(payload)两部分组成。基本首部长度固定为40字节,有效载荷也称为净负荷,最大64KB,允许有零个或多个扩展首部(extension header),因此有效载荷通常由扩展首部+数据组成。

- 版本(version):占4位,指明协议版本,IPv6值为6
- 通信量类(traffic class):又称为流量类型,占8位,用于区分不同的IPv6数据报的类别或优先级
- 流标号(flow label)占20位,用于标识一系列数据报(如用于实时音频或视频传输的数据报),属于同一个流的数据报都具有同样的流标号,它们由于实时性需求,将优于来自其他应用(如SMTP邮件)的数据报传输。对于流所经过路径上的路由器,路由器可以预分配资源给这些流(因为能提前知道后面还有流数据),因此这也是一种资源分配机制(这需要对路由器进行配置)。对于传统的电子邮件或非实时数据,流标号则没有用处,把它置为0即可。
- 有效载荷长度(payload length):占16位。它指明IPv6数据报除基本首部以外的字节数(所有扩展首部都算在有效载荷之内)。这个字段的最大值是64KB(65535字节)
- 下一个首部(next header):占8位,它相当于IPv4的协议字段或可选字段
- 当IPv6数据报没有扩展首部时,下一个首部字段的作用和IPv4的协议字段一样,它的值指出了基本首部后面的数据应交付IP层上面的哪一个高层协议(例如:6或17分别表示应交付运输层TCP或UDP)
- 当出现扩展首部时,下一个首部字段的值就标识后面第一个扩展首部的类型
- 跳数限制(hoplimit):占8位,用来防止数据报在网络中无限期地存在。源点在每个数据报发出时即设定某个跳数限制(最大为255跳)。每个路由器在转发数据报时,要先把跳数限制字段中的值减1。当跳数限制的值为零时,就要把这个数据报丢弃。
- 源地址:占128位,是数据报的发送端的IP地址
- 目的地址:占128位,是数据报的接收端的IP地址
IPv6的扩展首部
IPv6 通过“扩展首部链”的方式实现功能扩展,核心策略如下:
- 扩展首部放在基本首部之后,路由器主要处理基本首部,大多数扩展首部只在通信两端的源主机与目的主机上处理(逐跳选项首部除外),路由器无需关心,极大提高了转发性能。作为对比,IPv4首部中的选项,需要路由器一一检查
- 每一个扩展首部都由若干个字段组成,它们的长度也各不同。但所有扩展首部的第一个字段都是8位的“下一个首部”字段,此字段的值指出下一个扩展首部类型,方便链式解析,对于最后的上层协议首部,该字段会给出数据报要交付上层的哪个协议
- 当IPv6数据报中要使用多个扩展首部时,需要按照下述介绍顺序排列,这有助于设备按序高效解析
IPv6的扩展首部类型:
- 逐跳选项(Hop-by-Hop Options Header):路径上的每一个路由器都会处理该选项首部,它用于支持超大数据包(巨型帧,Jumbogram)或路由器告警等功能
- 目的站选项(第一类)(Destination Options Header):该选项可以在数据包出现两次:一次是在路由选择选项之前(第一类),另一次是在上层协议首部之前(第二类)。第一类通常搭配路由选择选项成对使用,路由选择选项指定一些中间结点后,该选项可以携带一些附加信息给这些中间结点看,而普通转发路径上的路由器不会理会。这可以用来给某个中间节点附带指令或元数据(如策略标记等),或者给后续分组预分配路由资源。与逐跳选项不同的时,所有路径上的路由器都会处理逐跳选项的信息,而只有路由选择指定的路由器才会处理目的站选项的信息
- 路由选择(Routing Header):类似于IPv4的源路由选项,允许数据包的源节点指定一条到达目的地的路径,指定一系列中间结点,数据包需要经过这些中间节点中一个或多个
- 分片(Fragment Header):用于分片,IPv6不允许在中间路由器上进行分片与重新组装,这种操作只能在源与目的地执行。如果路由器收到的IPv6数据报因太大而不能转发到出链路上的话,则路由器只需丢掉该数据报,并向发送方发回一个“分组太大”的ICMP差错报文即可,然后让发送方使用较小长度的IP数据报重发数据。该首部包含Fragment Offset、Identification、M标志(是否还有分片)字段
- 鉴别(AH,Authentication Header):用于校验数据完整性,数据源认证,防重放攻击,但它不会加密内容,加密由由ESP选项提供
- 封装安全有效载荷(ESP,Encapsulating Security Payload):用于提供加密,完整性保护,认证等功能,比AH选项更常用
- 目的选项首部(第二类)(Destination Options Header):可携带应用或协议相关的附加信息,给最终目的节点处理,这可以是应用或上层协议相关的附加信息
- 上层协议首部(Upper-Layer Header):类似于IPv4的协议选项,指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个协议进行处理,该选项的Next Header字段不再指出下一个扩展首部类型(因为它已经是最后一个),而是直接给出上层协议的标识,如:TCP=6、UDP=17、ICMPv6=58
IPv6移除的功能
IPv6报文移除了以下字段/功能:
分片/重新组装:IPv6不允许在中间路由器上进行分片与重新组装。这种操作只能在源与目的地执行。如果路由器收到的IPv6数据报因太大而不能转发到出链路上的话,则路由器只需丢掉该数据报,并向发送方发回一个“分组太大”的ICMP差错报文即可。然后让发送方使用较小长度的IP数据报重发数据。首部检验和:IPv4中,由于TTL字段的变化,所以路由不仅要校验首部,还要重新生成计算首部检验和,这很耗时。由于运输层(如TCP与UDP)和数据链路层(如以太网)协议会执行检验操作,因此被移除。选项:选项字段不再是标准IP首部的一部分了,该功能被做到了扩展首部里首部长度字段:IPv6首部长度是固定的(40字节)总长度字段:改用有效载荷长度字段服务类型字段:因为优先级和流标号字段实现了服务类型字段的功能标识、标志和片偏移字段:这些功能已包含在分片扩展首部中协议字段:改用下一个首部字段
IPv4向IPv6过渡
IPv4向IPv6过渡,主要有两种策略:双协议栈和隧道技术:
- 双协议(dual stack):指让一部分主机或路由器装载IPv4和IPv6双协议栈,这类主机也会持有两种IP地址,通信时会通过DNS来查询确定目标主机是支持IPv4还是IPv6,在和IPv6主机通信时采用IPv6地址,而和IPv4主机通信时则采用IPv4地址。如果是中间主机支持双协议,它可能需要把IPv6数据报首部转换为IPv4数据报首部,或者反过来,该过程中,IPv6首部中的某些字段可能无法恢复(如IPv6的流标号),这种信息的损失是使用首部转换方法所不可避免的
- 隧道技术(tunneling):该方法的要点就是在IPv6数据报要进入IPv4网络时,把IPv6数据报封装成为IPv4数据报,即把整个的IPv6数据报装载到IPv4数据报的数据部分,原来的IPv6数据报就好像在IPv4网络的隧道中传输。当数据报离开IPv4网络中的隧道时,再把数据部分(即原来的IPv6数据报)交给主机的IPv6协议栈。要使双协议栈的主机知道IPv4数据报里面封装的数据是一个IPv6数据报,就必须把IPv4首部的协议字段的值设置为41(41表示数据报的数据部分是IPv6数据报)。
ICMPv6
和IPv4一样,当路由器丢弃IPv6数据报,也需要使用ICMP来反馈一些差错信息,ICMP新版本称为ICMPv6,它比ICMPv4 要复杂得多。地址解析协议ARP和网际组管理协议IGMP的功能都已被合并到ICMPv6中,因此IPv6不再需要ARP和IGMP。
ICMPv6是面向报文的协议,其协议号(Next Header字段值)为58,有以下分类:
- 差错报文:用于报告IPv6数据包在传输过程中遇到的问题,如:目的不可达、数据包过大、跳数超限、头部字段错误等
- 信息报文:用于网络诊断,获取信息,如发送探测请求(ping发起),回应探测请求(ping响应)
- 邻站发现报文:核心应用,它基于邻居发现协议(NDP),替代了IPv4的ARP、ICMP路由器发现等功能,提供的功能有:
- 路由器请求 (RS):主机启动后,主动向本地链路范围发送,请求路由器立即发送RA报文,以快速获取网络前缀等配置信息
- 路由器通告 (RA):路由器周期性发送,或响应RS请求。用于宣告自己的存在,并携带地址前缀、跳数限制、MTU等网络配置参数,是IPv6无状态地址自动配置的关键
- 邻居请求 (NS):有三大功能:1.替代ARP实现地址解析,获取邻居的链路层地址。2. 重复地址检测(DAD),验证接口要使用的地址是否唯一;3. 邻居不可达检测(NUD),验证邻居是否仍可达
- 邻居通告(NA):用于响应NS报文,告知自己的链路层地址,或者主动发送以宣告链路层地址变更等
- 重定向:当网关接收了主机数据包,但发现存在更优的下一跳网关时,会发送此报文通知主机有一条更好的路径,不需要再发往这了
- 组播侦听发现协议报文:基于组播侦听发现协议(MLD),用于管理组播组成员,提供的功能包括路由器查询组播成员、主机加入组播组,主机离开组播组。
ARP地址解析协议
ARP地址解析协议用于将IP地址映射为物理地址,以解决主机知道目标设备的IP地址,但不知道MAC地址的问题(ARP仅用于IPv4,IPv6使用NDP来完成该功能)。ARP协议下,每一台主机都维护着一份ARP高速缓存(ARPcache)(操作系统中通常称为邻居表,neighbor table),里面存储了本局域网上的主机/路由器的IP地址到硬件地址的映射表。
ARP的工作流程
ARP高速缓存存储于操作系统内核态内存中,开机时,缓存为空,ARP根据需要查询所需IP的MAC地址,并在获得MAC地址后存入ARP高速缓存建立IP地址与MAC地址的映射关系。这意味着,ARP缓存中并没有本局域网上的所有主机/路由器的MAC地址,大多数情况下,主机的ARP高速缓存可能只存储了路由器或默认网关的MAC地址映射,因为大多数情况下主机通常只需要与路由器交互。ARP协议工作流程如下:
- 主机A要向主机B发送IP数据报时,先在其ARP高速缓存中查看有无主机B的IP地址。如果有,就把这个硬件地址写入MAC帧,如果没有,主机A就自动运行ARP,然后按后续步骤查询主机B的硬件地址
- ARP进程在本局域网上以广播形式发送一个ARP请求分组(目标MAC地址FF:FF:FF:FF:FF:FF)。ARP请求分组的内容类似于:“我的IP地址是209.0.0.5,硬件地址是00-00-C0-15-AD-18。我想知道IP地址为209.0.0.6的主机的硬件地址。”
- 在本局域网上的所有主机上运行的ARP进程都将收到此ARP请求分组,如果某个主机的IP地址与ARP请求分组中要查询的IP地址不一致,则丢弃该ARP请求分组
- 主机B的IP地址与ARP请求分组中要查询的IP地址一致,就收下这个ARP请求分组,并以单播形式向主机A发送ARP响应分组,响应分组的内容类似于:“我的IP地址是209.0.0.6,我的硬件地址是08-00-2B-00-EE-0A.”
- 主机A收到主机B的ARP响应分组后,就在其ARP高速缓存中写入主机B的IP地址到硬件地址的映射。通常而言,主机B收到A的ARP请求分组时,也会把主机A的MAC地址写入主机B自己的ARP高速缓存中
- ARP高速缓存中的地址映射具有生存时间,超过生存时间的映射会从高速缓存中删除,防止以下情况:主机A的ARP高速缓存里保存有B的硬件地址,但B的网络适配器突然坏了,B立即更换了一块,因此B的硬件地址就改变了,假定A继续使用ARP高速缓存中旧硬件地址,则将无法向B发送数据帧。生存时间保证了能即时更新ARP信息
ARP欺骗
由于ARP响应可以在没有对应请求的情况下被主动发送,且主机通常会无条件接受并更新缓存中的条目,攻击者可以在局域网内持续发送伪造的ARP响应,声称网关的IP地址对应自己的MAC地址,从而诱使受害主机的流量全部发往攻击者的机器,
防御手段通常包括静态ARP绑定、启用交换机的DAI动态ARP检测功能,或者使用支持端口安全特性的网络设备。此外,ARP仅适用于IPv4环境,IPv6中地址解析的功能已经交由NDP邻居发现协议承担,后者运行在ICMPv6之上,不再依赖广播而是使用组播,在效率和安全性上都有所改进。
ARP与DHCP
当一台新的主机加入一个网络,它既没有IP地址,也没有路由器的IP和MAC地址,如何工作:
- DHCP将先运行(因为ARP至少需要目标IP才能查询MAC),生成一个源IP地址0.0.0.0,目标IP地址255.255.255.255的DHCP发现报文,并封装在以太网帧中发出,该帧的源MAC地址为自身的地址,目的MAC地址为FF:FF:FF:FF:FF:FF
- 主机获得DHCP ACK报文后,提取出本机IP、子网掩码、默认网关IP地址、DNS服务器IP等信息后,写入操作系统的网络配置堆栈中,作为网卡的租约参数。
- 主机获得IP地址后,在进行网络通信时,在网络层,主机会用自己的 IP 地址与子网掩码做与运算,得出本地网络号;再用目标IP与子网掩码做与运算,以检查目标IP地址是否位于本网络下,
- 如果在本网络下,则把目标IP作为“下一跳IP”作为参数传递给邻居子系统,如果不在本网络下,则“下一跳IP”将是路由器的IP
- 主机在ARP缓存中查询“下一跳IP”的MAC地址,如果不存在,则通过ARP协议向本网络发起查询
ICMP网际控制报文协议
ICMP网际控制报文协议(Internet Control Message Protocol)允许主机或路由器在转发IP数据报时报告异常情况(如:IP首部存在无法解析的字段),同时提供少量查询功能(如ping),以通告发送方网络传输出现的问题。
ICMP报文格式

ICMP是IP层协议,ICMP报文由IP层直接封装而不需要上层参与,报文会直接装载到IP数据报的数据部分,ICMP报文的种类有两种:ICMP差错报告报文和ICMP询问报文,组成结构:
- ICMP报文的前4个字节格式一致,共有三个字段:
- 类型字段,根据不同类型填入不同值,常用值参考下一节
- 代码字段:用于进一步区分类型中的不同情况
- 检验和:由于IP数据报携带的检验和只检验首部,不检验数据部分,因此ICMP需要自带检验和,防止报文产生差错
- 中间4个字节的内容与ICMP的类型有关
- 最后是数据字段,长度取决于类型
ICMP差错报文
差错报文主要用于向发送方汇报异常情况
目的不可达:Type=3,用于表示数据报无法到达目标,可能原因有:
- 网络不可达(Network Unreachable):code=0,路由器没有匹配路由
- 主机不可达(Host Unreachable):code=1,网络可达,但目标主机不可达
- 协议不可达(Protocol Unreachable):code=2,目标主机不支持该传输协议
- 端口不可达(Port Unreachable):code=3,主机存在,但端口未监听(UDP 常见)
- 通信被管理员禁止:code=13
超时:Type = 11,用于处理数据报在网络中“存活时间耗尽”,可能原因有:
- TTL 超时:code=0,TTL减到0被路由器丢弃并返回ICMP
- 分片重组超时:code=1,分片未在规定时间内收齐
参数问题:Type = 12,当IP首部存在非法或无法解析的字段时触发,可能原因有:
- 首部字段错误:code=0
- 缺少必要选项:code=1
- 错误长度:code=2
重定向:Type = 5,用于优化路由路径,当主机向某个路由器发送数据,但该路由器发现去往目标网络存在一条更优的路径,则通知主机“下次直接走那条路,别绕我这儿了”,可能原因有:
- 重定向到网络:code=0
- 重定向到主机:code=1
需要分片:Type = 3,code=4,当一个数据包的大小超过了路径上某个链路的MTU,但IP头部又设置了”禁止分片”标志时,由器会丢弃该包并发送此ICMP 报文
源抑制(已废弃):Type = 4,Code = 0,通知发送方“网络拥塞,请降低速率”,现已被TCP拥塞控制替代
ICMP询问报文
常用的ICMP询问报文有两种:
- 回送请求和回送回答报文:某主机或路由器向一个特定的目的主机发出的询问,收到此报文的主机必须给源主机或路由器发送ICMP回送回答报文,这种询问报文用来测试目的站是否可达。回送请求(Echo Reques)报文的Type = 8,Code = 0,回送应答(Echo Reply)报文Type = 0,Code = 0
- 时间戳请求和回答:让某台主机或路由器回答当前的日期和时间,并以时间戳形式返回,主要测量时延或时钟差,目前该功能被NTP(时间同步)和PTP(高精度同步)替代
PING与Traceroute
分组网间探测PING(Packet InterNet Groper)是一个应用层诊断工具,它通过构造ICMP回送请求报文,经由IP层发送到目标主机,并接收ICMP回送应答,来测试两台主机之间的连通性,它是应用层直接使用网络层ICMP的一个例子,没有通过运输层的TCP或UDP
traceroute是一个应用层诊断程序(Windows下为tracert),通过TTL和ICMP超时报文逐步追踪源主机与目标主机之间的路径,其核心原理为发送一系列目标端口不可达(端口值值设置很大)的UDP报文,并逐步递增TTL,诱发中间路由器返回ICMP超时报文,大致流程为:
- 发送一个TTL = 1的探测报文,第一个路由器将TTL减为0后丢弃该报文,并返回ICMP “时间超过(Time Exceeded)”报文,从中得到第1跳路由器地址
- 发送TTL=2的报文,第2跳路由器返回ICMP超时,得到第2跳地址
- 不断递增 TTL,直到报文到达目标主机,由目标主机返回ICMP “端口不可达(Port Unreachable)
IP层分组转发的流程
互联网所有的分组转发都是基于目的主机所在的网络,路由器并不存储直接到达目的主机的完整路径,而是通过路由表,根据目的网络地址来匹配下一跳地址,将分组从一个路由器转发到下一个路由器,最终由目的网络上的路由器尝试直接交付给主机。某些特殊情况下也允许对特定的目的主机指明一个路由,而不是针对其所在网络,方便分组直接交付,这种路由叫做特定主机路由,常用于网络测试。此外,路由器还可采用默认路由(default route)作为兜底策略,当路由器在转发表中依次查找了特定主机路由和各类目的网络路由,却均未能找到匹配项时,默认路由将承担起收敛所有未知去向流量的职责,将把分组统一交给下一跳路由,默认路由配置形式极其简练,即目的网络地址与子网掩码均记为全零(0.0.0.0/0),以代表任意网络。
下一跳路由的IP与MAC
在IP数据报的首部中只有源IP地址和目的IP地址,没有地方可以用来指明“下一跳路由器的IP地址”。当路由器收到一个待转发的数据报,在从路由表得出下一跳路由器的IP地址后,不会把这个地址填入IP数据报,而是送交数据链路层的网络接口软件。网络接口软件负责把下跳路由器的IP地址转换成硬件地址(通过 ARP协议),并将此硬件地址放在链路层的MAC帧的首部,然后根据这个硬件地址找到下一跳路由器。因此,下一跳IP地址通常会被直接转换为MAC地址。
使用子网时的分组转发流程
一个完整的路由条目通常包含以下字段:
目的网络地址:目标网络或主机的地址
子网掩码:用于与目的IP地址进行按位“与”运算,以提取网络前缀
下一跳地址:通往目的网络下一个路由器的IP地址,如果可以直接交付(即路由器与该网络直连),此项通常显示为“直连”或接口自身的IP
出接口::路由器将分组从哪个物理或逻辑端口发出
度量值:有多条可达路径时,用于反映到达该网络距离或优劣的数值(如跳数、开销)
从IP数据报首部提取目的主机的IP地址D
若路由表中有目的地址为D的特定主机路由,则把数据报传送给路由表中所指明的下一跳路由器或主机
判断是否为直接交付(即交付终点是否为当前网络段):用与路由器直接相连的各网络的子网掩码和D逐位相“与”(AND操作),若结果与对应的网络地址匹配,则分组可以直接交付,查询ARP缓存把D转换成物理地址,把数据报封装成帧发送出去,转发任务结束
对路由表中的每一行(目的网络地址,子网掩码,下一跳地址),用其中的子网掩码和D逐位相“与”(AND操作),其结果为N。若N与该行的目的网络地址匹配,则把数据报传送给该行指明的下一跳路由器
若上述流程执行失败,而路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器
若上述匹配都执行失败,则报告转发分组出错
最长前缀匹配
在使用CIDR时,由于使用了网络前缀替代了旧有的网络地址,因此现代路由器路由表存储的是网络前缀而非目的网络地址,每个项目由“网络前缀”和“下一跳地址”等字段组成。查找路由表时可能会得到不止一个匹配结果,在选择匹配结果时,应当从匹配结果中选择具有最长网络前缀的路由,即执行最长前缀匹配
(longest-prefix matching),这是因为网络前缀越长,其地址块就越小,因而路由就越具体(more specific),匹配结果越精确,最长前缀匹配又称为最长匹配或最佳匹配。
| 目的地址206.0.71.130 | 206 | 0 | 01000111 | 10000010 |
|---|---|---|---|---|
| 206.0.68.0/22掩码 | 全1 | 全1 | 11111100 | 00000000 |
| 运算结果 | 206 | 0 | 01000100 | 0 |
| 206.0.68.0/22地址 | 206 | 0 | 01000100 | 0 |
| 目的地址206.0.71.130 | 206 | 0 | 01000111 | 10000010 |
|---|---|---|---|---|
| 206.0.71.128/25掩码 | 全1 | 全1 | 11111111 | 10000000 |
| 运算结果 | 206 | 0 | 01000111 | 10000000 |
| 206.0.71.128/25地址 | 206 | 0 | 01000111 | 10000000 |
路由选择协议
互联网的规模极其庞大,不同的单位内部会采用不同的路由选择协议,因此,可以把整个互联网划分为许多较小的自治系统AS(autonomous system),AS是在单一技术管理下的一组路由器,这些路由器使用一种自治系统内部的路由选择协议和共同的度量,一个大的ISP就是一个自治系统。此外,不同自治系统之间也需要传递信息,因此,互联网把路由选择协议分为两大类:
内部网关协议IGP(Interior Gateway Protocol):即在一个自治系统内部使用的路由选择协议(如RIP和OSPF协议),自治系统内部的路由选择叫做域内路由选择
外部网关协议EGP(External Gateway Protocol):由于旧的EGP与另外一个协议命名冲突,因此现代通常使用边界网关协议BGP(Border Gateway Protocol)这一称呼。当源主机和目的主机处在不同的自治系统中(这两个自治系统可能使用不同的内部网关协议),数据报传到一个自治系统的边界时,就需要依赖BGP协议将路由选择信息传递到另一个自治系统中,目前使用最多的边界网关协议是BGP的版本4(BGP-4)。自治系统之间的路由选择叫做域间路由选择
内部网关协议RIP
RIP(Routing Information Protocol)是最先得到广泛使用的内部网关协议,是一种基于距离向量的分布式路由选择协议,主要用于小型网络中。
RIP 协议要求网络中的每一个路由器都要维护从它自己到其他每一个目的网络的“距离向量”,具体流程为:
- RIP中“距离”的定义为跳数(而不是真的地理距离),本网络主机之间的距离为0,与目的网络之间要经过几个路由器,距离就为几。RIP允许一条路径最多只能包含15个路由器,距离等于16时即视为不可达,因此RIP只适用于小型互联网(如校园网、小型企业网)
- 不能在两个网络之间同时使用多条路由,RIP选择一条具有最少路由器的路由(即最短路由),哪怕还存在另一条高速(低时延)但路由器较多的路由。由于RIP仅根据跳数选择路径,无法根据带宽、延迟等更实际的因素进行选择,可能导致数据包未走最优路径
- RIP仅和相邻路由器交换信息,所交换的信息是当前本路由器的完整路由表,路由表中储存的是该路由器到本自治系统中所有网络的(最短)距离,以及到每个网络应经过的下一跳路由器。这些路由器会周期性(30秒)更新信息,以应对网络拓扑发生变化问题,但整个自治系统的路由器信息重新达成一致并且都更新为了最短路径(收敛)的速度较慢,可能导致短暂的路由黑洞或环路
RIP协议报文格式(了解)
现在较新的RIP版本是RIP2,支持变长子网掩码和无分类域间路由选择CIDR,并简单的鉴别过程支持多播,其报文基于UDP

RIP报文由首部和路由部分组成:
- 首部占4个字节,命令字段指出报文的意义。例如,1表示请求路由信息,2表示对请求路由信息的响应或未被请求而发出的路由更新报文。首部后填充0以进行4字节字的对齐。
- 路由部分由若干个路由信息组成,每个路由信息需要用20个字节:
- 地址族标识符(又称为地址类别)字段用来标志所使用的地址协议。如采用IP地址就令这个字段的值为2(原来考虑RIP也可用于其他非TCP/IP协议的情况)。
- 路由标记填入自治系统号ASN(Autonomous System Number),这是考虑使RIP 有可能收到本自治系统以外的路由选择信息。
- 后面指出某个网络地址、该网络的子网掩码、下一跳路由器地址以及到此网络的距离
一个RIP报文最多只能包括25个路由,因而RIP报文的最大长度是4+20x25=504字节。RIP2还具有简单的鉴别功能,若使用鉴别功能,则将原来写入第一个路由信息(20字节)的位置用作鉴别。这时应将地址族标识符置为全1(即0xFFFF),而路由标记写入鉴别类型,剩下的16字节为鉴别数据。在鉴别数据之后才写入路由信息,但这时最多只能再放入24个路由信息。
RIP的特点
- 实现简单,开销小
- 仅根据跳数选择路径,无法根据带宽、延迟等更实际的因素进行选择,不适合复杂网络环境
- 跳数达到16就视为不可达,且一个报文最多只包含25条路由条目,不适合大规模网络
- 网络出现故障时,信息收敛慢
内部网关协议OSPF
OSPF(Open Shortest Path First,开放最短路径优先)是互联网中应用最广泛的内部网关协议之一,采用Dijkstra提出的最短路径算法SPF,每台路由器都维护着一张完整的网络拓扑图,并基于此独立计算最优路径,它是为克服RIP的缺点开发出来的,其核心特点如下:
- 使用链路状态算法:OSPF使用分布式的链路状态协议(link state protocol),运行OSPF的路由器不直接交换路由表,而是通过链路状态通告(LSA)向整个网络泛洪自身的接口状态、链路开销、邻居关系等信息,而不是像RIP那样只发送距离向量。每台路由器收集所有LSA后,构建出完全相同的链路状态数据库(LSDB),这张数据库本质上是一张精确到每一条链路的网络拓扑图。随后,路由器以自身为根节点,运行Dijkstra最短路径优先(SPF)算法,计算出到达各目的网络的无环路最优路径。这种”先掌握全局,再独立计算”的机制从根本上避免了路由环路
- 快速收敛与触发更新:OSPF在网络稳定后仅依靠轻量的Hello报文维持邻居关系,当链路状态发生变化时才触发LSA的洪泛更新,而不是像RIP那样采用周期性(每30秒)的全量路由表广播,这种事件驱动的更新方式极大降低了协议自身的带宽开销,同时配合SPF算法的增量计算能力,使得网络故障后的路由重收敛时间远低于距离矢量协议
- 层次化区域架构:为了使OSPF能够用于规模很大的网络,OSPF将一个自治系统划分为若干个区域(area),并用一个32位的区域标识符标识区域。这样洪泛法交换链路状态信息的范围局限于每一个区域而不是整个的自治系统,减少了整个网络上的通信量。在一个区域内部的路由器只知道本区域的完整网络拓扑,而不知道其他区域的网络拓扑的情况。为了使每一个区域能够和本区域以外的区域进行通信,OSPF使用层次结构的区域划分,上层的区域叫做主干区域(backbonerea,标识符规定为0.0.0.0),主干区域的作用是用来连通其他下层区域。每一个区域至少有一个区域边界路由器(area border router)负责收纳该区域的信息,并与主干区交互。整个自治系统也会有一个自治系统边界路由器负责与其他自治系统交换路由信息
- 支持负载均衡:OSPF允许管理员给每条路由指派不同的代价,当到达同一目的地存在多条开销相同的路径时,OSPF可以将流量平均分配到这些链路上,提升链路利用率与冗余性
- 支持CIDR,且安全性高:OSPF支持可变长度的子网划分和无分类的编址CIDR,且所有在OSPF路由器之间交换的分组都支持鉴别的功能,因而保证了仅在可信赖的路由器之间交换链路状态信息
OSPF协议报文格式

OSPF不用UDP而是直接用IP数据报传送(其IP数据报首部的协议字段值为89)。OSPF 构成的数据报很短,这样做可减少路由信息的通信量,且可以减少需要分片的情况。OSPF分组使用24字节的固定长度首部,分组的数据部分可分组中的一种首部字段有:
- 版本:当前的版本号是2
- 类型:可以是五种类型分组中的一种:
- 问候(Hello)分组:用来发现和维持邻站的可达性,OSPF 规定,每两个相邻路由器每隔10秒钟要交换一次问候分组,以确知哪些邻站是可达的。若有40秒钟没有收到某个相邻路由器发来的问候分组,则可认为该相邻路由器是不可达的,应立即修改链路状态数据库,重新计算路由表
- 数据库描述(Database Description)分组:向邻站给出自己的链路状态数据库中的所有链路状态项目的摘要信息
- 链路状态请求(Link State Request)分组:向对方请求发送某些链路状态项目的详细信息
- 链路状态更新(Link State Update)分组:用洪泛法对全网更新链路状态
- 分组长度:包括OSPF首部在内的分组长度,以字节为单位
- 路由器标识符:标志发送该分组的路由器的接口的IP地址
- 区域标识符:分组属于的区域的标识符
- 检验和:用来检测分组中的差错
- 鉴别类型:目前只有两种,0(不用)和1(口令)
- 鉴别:鉴别类型为0时就填入0,鉴别类型为1则填入8个字符的口令
边界网关协议BGP
不同自治系统(AS)内部使用不同的内部路由协议,无法直接交换路由信息,同时,AS之间的路由选择必须满足复杂的商业或安全策略,比如强制特定流量绕行或禁止经过某些网络,不同AS之间路由需要一个特定的协议——边界网关协议BGP。
边界网关协议BGP的目标只能是力求寻找一条能够到达目的网络且比较好的路由(不形成环路兜圈子),而并非要寻找一条最佳路由。BGP采用了路径向量(path vector)路由选择协议,它与距离向量协议(如RIP)和链路状态协议(如OSPF)都有很大的区别,BGP的特点:
- 每一个自治系统拥有至少一个路由器作为该自治系统的BGP发言人(BGP Speaker),BGP发言人代表该自治系统负责与其他AS交换路由信息,这意味着每一个BGP发言人除了必须运行BGP协议外,还必须运行该自治系统所使用的内部网关协议,如OSPF或RIP。交换路由信息的两个BGP发言人,彼此成为对方的邻站(neighbor)或对等站(peer)。
- BGP发言人之间交换路由信息,就要先建立TCP连接(端口号为179),并在此连接上建立BGP会话(session),利用BGP会话交换路由信息,如增加了新的路由,或撤销过时的路由,以及报告出差错的情况等等
- 边界网关协议BGP所交换的路由信息还包含网络可达性,即当前自治系统要到达某个网络(用网络前缀表示)所要经过的一系列自治系统。当BGP发言人互相交换了网络可达性的信息后,各BGP发言人就根据所采用的策略从收到的路由信息中找出到达各自治系统的较好路由,并构造出的自治系统连通图,它是树形结构,不存在回路
- BGP支持无分类域间路由选择CIDR,因此 BGP的路由表也就应当包括目的网络前缀、下一跳路由器,以及到达该目的网络所要经过的自治系统序列
BGP报文格式

BGP-4是当前主流版本,报文有四种类型,它们具有同样的通用首部,长19字节,有三个字段:
- 标记(marker):长16字节,用来鉴别所收到BGP报文的真实性,当不使用鉴别时,标记字段要置为全1
- 长度:指出包括通用首部在内的整个BGP 报文以字节为单位的长度,最小值是19,最大值是4096
- 类型:值为1到4,分别对应于四种类型的BGP报文:
- OPEN(打开)报文:用来与相邻的另一个BGP发言人建立关系,使通信初始化,如果邻站同意,就用KEEPALIVE报文响应,以建立连接。OPEN报文共有6个字段,即版本(1字节,现在的值是4)、本自治系统号(2字节,使用全球唯一的16位自治系统号,由ICANN地区登记机构分配)、保持时间(2字节,以秒计算的保持为邻站关系的时间)、BGP标识符(4字节,通常就是该路由器的IP地址)、可选参数长度(1字节)和可选参数
- UPDATE(更新)报文:可以用来通告某一路由的信息,也可以撤销或增加路由,撤销路由可以一次撤销许多条,但增加新路由时,每个更新报文只能增加一条。UPDATE报文共有5个字段,即不可行路由长度(2字节,指明下一个字段的长度)、撤销的路由(列出所有要撤销的路由)、路径属性总长度(2字节,指明下一个字段的长度)、路径属性(定义在这个报文中增加的路径的属性)和网络层可达性信息NLRI(Network Layer Reachability Information)。最后这个字段定义发出此报文的网络,包括网络前缀的位数、IP地址前缀。
- KEEPALIVE(保活)报文:用来周期性地证实邻站的连通性,它只有BGP的19字节长的通用首部
- NOTIFICATION(通知)报文:用来发送检测到的差错,有3个字段,即差错代码(1字节)、差错子代码(1字节)和差错数据(给出有关差错的诊断信息)
路由器
路由器的结构

路由器是一种具有多个输入端口和多个输出端口的专用计算机,其任务是转发分组。从路由器某个输入端口收到的分组,按照分组要去的目的地(即目的网络),路由器会将该分组从路由器的某个合适的输出端口转发给下一跳路由器。路由器结构可划分为两大部分:
- 路由选择部分也叫做控制部分,属于控制平面,其核心构件是路由选择处理机。路由选择处理机的任务是根据所选定的路由选择协议构造出路由表,同时经常或定期地和相邻路由器交换路由信息而不断地更新和维护路由表,路由选择的核心是路由选择协议,参考路由选择协议章节。
- 分组转发部分由三部分组成:交换结构、一组输入端口、一组输出端口(这里的端口指硬件接口),位于数据平面
交换结构
交换结构(switching fabric)又称为交换组织,它的作用就是根据转发表(forwarding table)对分组进行处理,将某个输入端口进入的分组从一个合适的输出端口转发出去,注意交换结构使用转发表作为处理依据,路由表与转发表的区别:
- 路由表负责收集和筛选当前网络内的所有路径信息,存储的是整个网络的拓扑结构,信息全面且复杂,包含到达同一目标网络的多条路径,以及路由协议相关的属性,如度量值、管理距离等。转发表是根据路由表生成出来的,存储了从路由表中总结出的单一精简信息(通常是最佳路径的关键信息),如目的网络、下一跳IP、出接口等
- 路由表工作在控制平面,运行在路由器的CPU和通用内存中,负责处理路由协议、计算路径。转发表工作在数据平面,通常存储在专门的高速硬件(如TCAM)中,以实现线速转发
- 路由表更新相对频繁(受网络拓扑变化影响),查表速度较慢(软件查表)。转发表的更新由路由表触发,查表速度极快(硬件查表)

路由器常用的交换结构有三种:
- 通过存储器:该结构最早使用,早期的路由器就是使用计算机的CPU作为路由器的路由选择处理机,路由器的输入和输出端口类似于I/O设备。当路由器的某个输入端口收到一个分组时,就用中断方式通知路由选择处理机。然后分组就从输入端口复制到存储器中。路由器处理机从分组首部提取目的地址,查找路由表,再将分组复制到合适的输出端口的缓存中。许多现代的路由器也通过存储器进行交换,但现代路由器对目的地址的查找和分组在存储器中的缓存都是在输入端口中进行的,速度较快
- 通过总线:数据报从输入端口通过共享的总线直接传送到合适的输出端口,而不需要路由选择处理机的干预。由于总线是共享的,因此在同一时间只能有一个分组在总线上传送,容易被阻塞。但现代的技术已经可以将总线的带宽提高到每秒吉比特的速率,因此许多的路由器产品也使用这种通过总线的交换方式。
- 通过互连网络:这种纵横交换结构有2N条总线,可以使N个输入端口和N个输出端口相连接,这取决于相应的交叉结点是使水平总线和垂直总线接通还是断开。当输入端口收到一个分组时,就将它发送到与该输入端口相连的水平总线上。若通向所要转发的输出端口的垂直总线是空闲的,则在这个结点将垂直总线与水平总线接通,然后将该分组转发到这个输出端口。但若该垂直总线已被占用,则后到达的分组会被阻塞,需要在输入端口排队。
输入输出端口

路由器的输入和输出端口都有物理层、数据链路层和网络层的三层处理模块,结构类似:
- 物理层进行比特的接收
- 数据链路层则按照链路层协议接收传送分组的帧
- 网络层的处理模块首先需要区分分组,若接收到的分组是路由器之间交换路由信息的分组(如RIP或OSPF分组等),则把这种分组送交路由器的路由选择部分中的路由选择处理机。若接收到的是数据分组,则按照分组首部中的目的地址查找转发表。网络层的处理模块设有缓冲区,实际上它就是一个队列。当路由器从链路接收分组的速率快于路由器处理速率(对输入端口),或者交换结构传送过来的分组的速率超过输出链路的发送速率时(对输出端口),来不及处理的分组会暂时存放在这个队列中,这会造成时延,当缓冲区溢出,多余的分组会被丢弃,这也是路由器中分组丢失的原因之一
- 路由器的输入端口和输出端口通常直接做在路由器的线路接口卡上,输入端口中的查找和转发功能在路由器的交换功能中是最重要的,为了使交换功能分散化,往往把复制的转发表放在每一个输入端口中,路由选择处理机负责对各转发表的副本进行更新,这些副本常称为影子副本(shadow copy),分散化交换可以避免在路由器中的某一点上出现瓶颈。
- 路由器工作时,最理想的情况是路由器的处理速度能够跟上物理链路的传输速率,能保证数据无阻塞、无丢失的流转。路由器接口能处理的最大物理层比特率称为线速(line speed 或 wirespeed),通常以比特率作为单位,如Mbps,通常也用Mpps(百万分组每秒)为单位来描述一个路由器对收到的分组的处理速率有多高。
IP多播
一对多通信可以基于单播实现,也可以基于多播实现。单播要求源端为每个接收者独立发送一份数据副本,资源开销会随规模线性增长。如:某视频服务器要向90台主机传送同样的视频节目,单播模式下,源服务器要发送90个单播,即将同一个视频分组发送90个副本,极其消耗网络资源。多播则以网络复制为核心,源端仅发送一份数据,由沿途路由器按需复制分发,从而实现常量级的带宽占用,当分组到达目的局域网时,由于局域网具有硬件多播功能,因此不需要复制分组,在局域网上的多播组成员都能收到这个视频分组,当多播组的主机数量很大(如成千上万),多播方式能显著减少网络的资源消耗。
IP多播(multicast,曾被译为组播)有以下特点:
- 需要多播的数据报称为多播数据报。多播数据报首部的协议字段值为2,表明该数据报使用的是网际组管理协议IGMP
- 接收多播数据报的主机共同组成一个多播组,这些主机通常分散在不同的网络中,由多播路由器负责将多播数据报转发到这些网络中
- 支持多播协议的路由器称为多播路由器(multicast router),多播路由器在转发多播数据报时,会根据需要将其复制为多个副本,转发到不同的目标网络。
- 数据报传输时需要有目的地址,但如此多的主机地址不可能都写到数据报的首部中,因此多播数据报使用多播地址(即D类地址,范围224.0.0.0-239.255.255.255)作为目的地址。多播地址同时也是多播组的标识,一个D类地址就代表一个多播组,这意味着互联网上可以有228(超过2.6亿)个多播组同时运行。多播地址只能用于目的地址,不能作为源地址
- 多播数据报只提供“尽最大努力交付”,不保证一定送达多播组内的所有成员
- 多播数据报也不会产生ICMP差错报文,因此PING多播地址将永远不会收到响应
- IP多播可以由没加入任何多播组的主机发出,多播数据报传输时也可以通过没有组成员接入的网络,只作为“路过”
多播的实际用途
多播一点发送,多点接收的特性很适合直播、 流媒体分发等领域,但实际应用中,由于多播需要路由器等底层硬件支持IGMP等多播协议,且需要维护多播转发表,如果在全球互联网上为几万个直播频道都维护这种状态表,核心路由器的内存和CPU会瞬间耗尽,因此实际生活中的多播并不用于互联网直播,但依旧会用于:
- IPTV / 运营商电视,不同于互联网直播,运营商数字电视通过运营商部署多播路由器等方式,可以不依赖于用户硬件的方式实现流媒体分发
- 局域网服务发现:智能家居设备发现
- 金融行业:用于快速同步、分发行情数据
- 企业内部:高效地为服务器、网关集群分发配置更新、软件发布、状态同步等信息
局域网的硬件多播
参考链路层,“以太网的MAC层”章节下的“IPv4多播地址到MAC地址的映射”
网际组管理协议IGMP
IP多播的核心设计目标是让数据只发送给真正感兴趣的主机,而不是网络中的所有节点。但路由器本身并不知道某个子网内是否存在希望接收特定多播组数据的主机,源主机和链路上的路由器也无法确定是否应该向某个网络转发该多播数据报,多播组中的主机可能分散在完全不同网络中,为了解决这个“接收者在哪”的问题,IP层引入了网际组管理协议IGMP (Internet Group Management Protocol)
IGMP使用IP数据报传递其报文(即IGMP报文加上IP首部构成IP数据报,报文格式略),工作可分为两个阶段:
第一阶段:当某台主机加入新的多播组时,该主机应向多播组的多播地址发送一个IGMP报文,声明自己要成为该组的成员。本地的多播路由器收到IGMP报文后,还要利用多播路由选择协议把这种组成员关系转发给互联网上的其他多播路由器。
第二阶段:组成员关系是动态的。本地多播路由器要周期性地探询本地局域网上的主机,以便知道这些主机是否还继续是组的成员。只要有一台主机对某个组响应,那么多播路由器就认为这个组是活跃的。但一个组在经过几次的探询后仍然没有一台主机响应,多播路由器就认为本网络上的主机已经都离开了这个组,因此也就不再把这个组的成员关系转发给其他的多播路由器。
IGMP的一些细节:
- 在主机和多播路由器之间的所有通信都是使用IP多播。只要有可能,携带 IGMP报文的数据报都用硬件多播来传送。因此在支持硬件多播的网络上,没有参加IP多播的主机不会收到IGMP报文
- 多播路由器在探询组成员关系时,只需要对所有的组发送一个请求信息的询问报文,而不需要对每一个组发送一个询问报文(虽然也允许对一个特定组发送询问报文)。默认的询问速率是每125秒发送一次(通信量并不太大)
- 当同一个网络上连接有几个多播路由器时,它们能够迅速和有效地选择其中的一个来探询主机的成员关系。因此,网络上多个多播路由器并不会引起IGMP通信量的增大
- 在IGMP的询问报文中有一个数值N,它指明一个最长响应时间(默认值为10秒)。当收到询问时,主机在0到N之间随机选择发送响应所需经过的时延。因此,若一台主机同时参加了几个多播组,则主机对每一个多播组选择不同的随机数。对应于最小时延的响应最先发送
- 同一个组内的每一台主机都要监听响应,只要有本组的其他主机先发送了响应,自己就可以不再发送响应了。这样就抑制了不必要的通信量。
多播路由器并不需要保留组成员关系的准确记录,因为向局域网上的组成员转发数据报是使用硬件多播。多播路由器只需要知道网络上是否至少还有一台主机是本组成员即可。实际上,对询问报文每一个组只需有一台主机发送响应 - 多播数据报的发送者和接收者都不知道(也无法找出)一个多播组的成员有多少,以及这些成员是哪些主机
- 如果一台主机上有多个进程都加入了某个多播组,那么这台主机对发给这个多播组的每个多播数据报只接收一个副本,然后给主机中的每一个进程发送一个本地复制的副本
多播路由选择协议
IGMP解决了多播组中的主机在哪的问题,多播路由选择协议解决的则是如何转发的问题。多播过程中多播组中的成员是动态变化的,随时会有主机加入或离开这个多播组。多播路由选择实际上就是要找出以源主机为根节点的多播转发树。在该转发树上,每一个多播路由器向树的叶节点方向转发收到的多播数据报,但在多播转发树上的路由器不会收到重复的多播数据报(即多播数据报不应在互联网中形成环路转发)。不同的多播组对应不同的多播转发树。同一个多播组,对不同的源点也会有不同的多播转发树。
历史上曾出现多种实用的多播路由选择协议(目前工程上最核心的协议是PIM,即Protocol Independent Multicast,协议无关组播),它们在转发多播数据报时通常使用以下的三种方法:
洪泛与剪除:该方法适用于较小的多播组,要求所有组成员接入的局域网相邻。一开始,路由器以洪泛(即广播)方式转发多播数据报。为避免兜圈子,采用反向路径广播RPB(Reverse Path Broadcasting)策略,要点是:路由器收到多播数据报时,先检查其是否从源点路径传来的。进行这种检查很容易,只要从本路由器寻找到源点的最短路径上(之所以叫做反向路径,因为在计算最短路径时是把源点当作终点)的第一个路由器是否就是刚才把多播数据报送来的路由器。若是,则向除进入方向外的所有方向转发;否则丢弃。若存在多条等长最短路径,则选择其中相邻路由器IP地址最小的一条。
如上图中,假定各路由器之间的距离都是1。路由器R1收到源点发来的多播数据报后,向R2和R3转发。R2发现R1在自己到源点的最短路径上,因此向R3和R4转发收到的数据报且不会向R1转发。而R3发现R2不在自己到源点的最短路径上,因此会丢弃R2发来的数据报。其他路由器也执行同样的策略。R7到源点有两条最短路径:R7-R4-R2-R1-源点和R7-R5-R3-R1-源点。假定R4的IP地址比R5的IP地址小,将使用前一条最短路径。因此R7只转发R4传过来的数据报,而丢弃R5传过来的数据报。最后就得出了用来转发多播数据报的多播转发树(图中用粗线表示),以后就按这个多播转发树来转发多播数据报。这样就避免了多播数据报兜圈子,同时每一个路由器也不会接收重复的多播数据报。如果在多播转发树上的某个路由器发现它的下游树枝(即叶节点方向)已没有该多播组的成员,就应把它和下游的树枝一起剪除。图4-57中虚线椭圆表示剪除的部分。当某个树枝有新增加的组成员时,可以再接入到多播转发树上。loading
隧道技术(tunneling):该技术适用于多播组的位置在地理上很分散的情况。假设两个网络A和B都支持多播,但它们之间的网络并不支持多播,无法按多播地址转发数据报,为此,网络A的路由器可以对多播数据报进行再次封装,即再加上普通数据报首部,使之成为向单一目的站发送的单播(unicast)数据报,单播数据报到达网络B后,再由网络B中的路由器剥去其首部,将其恢复成原来的多播数据报,继续向多个目的站转发。A到B之间的传输就好像穿越了隧道一样,这种使用隧道技术传送数据报又叫做 IP中的IP(IP-in-IP)。
基于核心的发现技术:这种方法对于多播组的大小在较大范围内变化时都适合。这种方法是对每一个多播组G指定一个核心(core)路由器,给出它的IP单播地址。核心路由器按照之前的方法创建出对应于多播组G的转发树。如果有一个路由器A向这个核心路由器发送数据报,那么它在途中经过的每一个路由器都要检查其内容。当数据报到达参加了多播组G的路由器B时,B就处理这个数据报:
- 如果A发出的是一个多播数据报,且其目的地址是G的组地址,B就向多播组G的成员转发这个多播数据报。
- 如果A发出的数据报是一个请求加入多播组G的数据报,B就把这个信息加到它的路由中,并用隧道技术向A转发每一个多播数据报的一个副本,A将成为另一个网络的核心路由器,这样,参加到多播组G的路由器就从核心向外增多了,扩大了多播转发树的覆盖范围。
VPN与NAT
由于IP地址的紧缺,一个机构能够申请到的IP地址很有限,而且很多机构并不需要把所有的主机都接入公网,大部分主机主要还是和本机构内的其他主机进行通信(如:大型商场或酒店用于营业的计算机)。这些机构内部通常会使用ABC类中预留好的私有地址作为主机地址:
- A类10.0.0.0 – 10.255.255.255(10.0.0.0/8)
- B类172.16.0.0 – 172.31.255.255(172.16.0.0/12)
- C类192.168.0.0 – 192.168.255.255(192.168.0.0/16)
这些地址又称为本地地址,采用本地地址的互连网络称为专用网或本地局域网。
虚拟专用网VPN
有时一个机构的多个部门分散在各地,这些部门之间的数据交换往往需要经过公网(也可以拉一条私有专线但成本高昂),此时需要在各局域网的网关之间建立VPN隧道,使分处异地的多个局域网在逻辑上连通为一个整体。这种利用公网作为各专用网的通信载体,从而打造出来的专用网称为虚拟专用网VPN(Virtual Private Network),称为“虚拟”是因为它只是效果上和专用网一样,但并不是真的只用内部专线,VPN在公网传输的数据通常需要严格加密。
以下是通过IP隧道技术实现的虚拟专用网,假定某个机构在两个相隔较远的场所建立了专用网A和B,其网络地址分别为专用地址10.1.0.0和10.2.0.0,专用网A和B中的路由器R1和R2至少要有一个公网IP地址,它们在内网使用的则是专用网的本地地址。

如果场所A的主机X要和另一个场所B的主机Y通信,则需要经过路由器R1和R2。主机X向主机Y发送的IP数据报的源地址是10.1.0.1,目的地址是10.2.0.3。这个数据报先作为本机构的内部数据报从X发送到路由器R1。路由器R1收到内部数据报后,发现其目的网络必须通过互联网才能到达,于是把整个内网数据报进行加密,然后重新加上新的数据报的首部,封装成可以在互联网上发送的外部数据报,其源地址是路由器R1的IP地址125.1.2.3,目的地址是路由器R2的IP地址194.4.5.6。路由器R2收到数据报后将其数据部分取出进行解密,恢复出原来的内部数据报(目的地址是10.2.0.3),交付主机Y。由此,虽然X向Y发送的数据报是通过了公用的互联网,但在效果上就好像是在本部门的专用网上传送一样。
VPN具体分为以下类型:
- 内联网VPN(intranet VPN):如上述一样,由场所A和B的内部网络所构成的虚拟专用网VPN称为内联网VPN,场所A和B都属于同一个机构
- 外联网VPN(extranet VPN):当VPN需要有某些外部机构(通常就是合作伙伴)接入时,这样的VPN称为外联网VPN,它的架构通常也是“网关到网关”的,但精髓在于极度严格的访问控制。通过外联网VPN连入的外部伙伴,只能访问到被明确授权的特定服务器或应用
- 远程接入VPN(remote accessVPN):当员工在外地工作,需要访问内网,或者召开电话会议或视频会议时。远程接入VPN 可以满足这种需求,外地工作的员工通过拨号接入互联网,而驻留在员工个人电脑中的VPN软件可以在员工的个人电脑和公司的主机之间建立VPN 隧道,与前两者的根本不同在于,连接的一端不再是固定的网络,而是一个主机或终端
网络地址转换NAT
本地局域网中,公网IP地址通常由路由器持有,局域网中的主机只拥有本地地址(或称为私有地址),当这些主机需要与互联网上的主机通信时,需要通过网络地址转换NAT(Network Address Translation)将本地地址转换为公网IP地址,并向NAT转换表中添加映射信息,这一操作由NAT路由器在数据包转发过程中透明完成。在实际工程中,最常见的是网络地址与端口号转换NAPT(Network Address and Port Translation),它不仅改写IP地址,还会复用传输层端口,从而允许多台内网主机共享同一个公网IP。
现在常用的NAT转换表本质上是一个以(协议,源IP,源端口,目的IP,目的端口)这一五元组为核心索引的状态表,路由器在处理出站报文时,会将内网主机的源IP替换为公网IP,并动态分配一个新的源端口,同时在转换表中记录这条映射关系;当外部主机返回响应报文时,路由器再根据该表项进行反向改写,将目的IP和端口恢复为对应的内网主机,从而完成一次完整的双向通信。注意,这里NAT路由器直接对数据报中的元数据进行状态化修改,不需要创建和使用套接字来修改端口号(这是操作系统层面的内容)。
| 协议 | LAN端 | WAN端 | 目标 |
|---|---|---|---|
| TCP | 192.168.0.3:1234 | 172.38.1.5:40001 | 8.8.8.8:80 |
| UDP | 192.168.0.3:1234 | 172.38.1.5:40001 | 8.8.8.8:80 |
多协议标记交换MPLS
多协议标记交换MPLS(MultiProtocol Label Switching)是一种介于链路层与网络层之间的转发技术,具有以下特色:
- MPLS认为传统基于IP地址查路由表的方式速度过慢,因此MPLS的核心思想是给数据包打上一个短标签(label),然后通过查询标签的方式实现快速转发,比最长前缀匹配速度更快。但现代路由器通过专用集成电路(ASIC)实现硬件转发,不再是早期CPU查路由表的方式,因此转发速度已经不再是MPLS的优势
- 传统IP路由通常走“最短路径”,容易导致某些链路拥塞。MPLS可以人为指定路径,使流量分散到多个不同路径上,实现链路负载均衡避开拥塞
- 能有效支持VPN,因此被广泛用于运营商VPN网络MPLS L3 VPN
- MPLS可以承载IPv4、IPv6、以太网帧、甚至非IP流量,它的传输机制与上层网络层协议的类型解耦,这也是“多协议”的由来
工作流程

支持MPLS的路由器称为标记交换路由器LSR(Label Switching Router)。LSR同时具有标记交换和路由选择两种功能,有诸多彼此相邻的LSR的域称为MPLS域(MPLS domain),MPLS的一个重要特点就是在MPLS域的入口处,给每一个IP数据报打上固定长度“标记”,然后对打上标记的IP数据报用硬件进行转发,极大地加快了交换速度,“交换”也表示在转发时不再上升到第三层查找转发表,而是根据标记在第二层(链路层)用硬件进行转发。MPLS可使用多种链路层协议,如PPP、以太网、ATM 以及帧中继等,具体的工作流程为:
- MPLS域中的各LSR使用专门的标记分配协议LDP(Label Distribution Protocol)交换报文,并找出和特定标记相对应的标记交换路径LSP(Label Switched Path)。如图中的路径A一B一C一D。各LSR根据这些路径构造出转发表。这个过程和路由器构造自己的路由表相似。MPLS是面向连接的,因此LSP上的第一个LSR根据IP数据报的初始标记确定整个的标记交换路径后,这个路径后续就不变了。这种由入口LSR确定后面转发路径的方式称为显式路由选择(explicit routing)
- 当一个IP数据报进入到MPLS域时,MPLS入口结点(ingress node)就给它打上标记,这本质上是插入一个MPLS首部,并按照转发表把它转发给下一个LSR。以后的所有LSR都按照标记进行转发。给IP数据报打标记的过程称为分类(classification)。大多数分类只使用了第三层IP首部中的字段信息,如源IP地址和目的IP地址等。大多数运营商实现了第四层(运输层)分类(除了要检查IP首部外,运输层还要检查TCP或UDP首部中的协议端口号),而有些运营商则实现了第五层(应用层)分类(更进一步地检查数据报的内部并考虑其有效载荷)。
- 每经过一个LSR,分组中的标记就需要更换一次,即把入标记更换成为出标记,称为标记对换(label swapping)。标记的信息来源于转发表,如图中的标记交换路由器B从入接口0收到一个入标记为3的IP数据报,根据转发表应当把该IP数据报从出接口1转发出去,同时把标记对换为1
| 入接口 | 入标记 | 出接口 | 出标记 |
|---|---|---|---|
| 0 | 3 | 1 | 1 |
- 当IP 数据报离开 MPLS 域时,MPLS 出口结点(egress node)就把 MPLS 的标记去除,把IP数据报交付非MPLS的主机或路由器,之后按照普通的转发方法进行转发。
转发等价类FEC
MPLS有个很重要的概念:转发等价类FEC(Forwarding Equivalence Class),它是一系列IP数据报的集合,标记交换路由器LSR将按照同样方式,从同样接口转发到同样的下一跳地址,并且这些数据报具有同样服务类别和同样丢弃优先级等,可以按照下列方式分类IP数据报:
- 目的IP地址与某一个特定IP地址的前缀匹配的IP数据报;
- 所有源地址与目的地址都相同的IP数据报;
- 具有某种服务质量需求的IP数据报。
除了上述方法,网络管理员可以通过任意方法划分FEC,入口结点并不是给每一个IP数据报指派一个不同的标记,而是给属于同样FEC的IP数据报指派同样的标记,FEC和标记是一一对应的关系。管理员可以根据FEC,在入口结点处配置不同的标记,而标记又可以配置为不同的路径,因此管理员可以为不同的FEC指定不同传输路径,这种均衡网络负载的做法也称为流量工程TE(Traffic Engineering)或通信量工程
MPLS首部位置与格式
MPLS首部位于第二层和第三层之间,位置也是在以太网帧首部和IP数据报首部之间插入了一个4字节MPLS首部,在把加上MPLS首部的IP数据报封装成以太网帧时,以太网的类型字段在单播的情况下设置为884716,而在多播的情况下为884816。这样,接收方可以用帧的类型来判决这个帧是携带了MPLS标记还是一个常规的IP数据报。

MPLS首部共包括以下四个字段:
- 标记值:占20位,因此MPLS可以同时容纳高达2220个流(即1048576个流)。但实际上几乎没有哪个MPLS 实例会使用很大数目的流,因为通常需要管理员人工管理和设置每条交换路径。
- 试验:占3位,目前保留用于试验
- 栈S:占1位,在有“标记栈”时使用
- 生存时间TTL:占8位,用来防止MPLS分组在MPLS域中兜圈子