前言
网际协议(IP, Internet Protocol)是用于分组交换数据网络的协议,又称互联网协议,是整个 TCP/IP 协议族的核心,也是构成互联网的基础。
今天有两个版本的 IP 正在使用,一个是广泛部署的 IP 版本 4 ,这通常简单地称为 IPv4 ,还有一个是 IP 版本 6 ,它已经被提议替代 IPv4 。
IPv4 数据报格式
- 版本:占 4 比特,规定了数据报的 IP 协议版本,如 IPv4 或 IPv6
- 首部长度:占 4 比特,标识 IP 数据报的头部长度,单位是字节,大多数 IP 数据报不包含选项,所以一般的 IP 数据报具有 20 字节的首部
- 服务类型:占 8 比特,标识数据类型,以便使不同类型的 IP 数据报(例如一些特别要求低时延、高吞吐量或可靠性的数据报)能相互区别开来
- 数据报长度:占 16 比特,标识 IP 数据报的总长度,单位是字节。因为该字段长为 16 比特,所以 IP 数据报的理论最大长度为 65536 字节,然而数据报很少有超过 1500 字节的
- 标识、标志、片偏移:与 IP 分片有关
- 寿命:Time-To-Live ,用来确保数据报不会永远(如由于长时间的路由环路)在网络中循环。每当一台路由器处理数据报时,该字段的值减 1 ,若 TTL 字段减为 0 ,则该数据报必须丢弃
- 协议:标识 IP 数据报的数据部分应交给那个特定的传输层协议,仅当 IP 数据报到达最终目的地时才会有用
- 校验和:用于帮助路由器检测收到的 IP 数据报中的比特错误
- 源和目的 IP 地址:当某源生成一个数据报时,它在源 IP 字段中插入它的 IP 地址,在目的 IP 地址字段中插入其最终目的地的地址,通常源主机通过 DNS 查找来决定目的地址
- 选项:选项字段允许 IP 首部被扩展
- 数据:有效载荷
- 为什么 TCP/IP 在传输层和网络层都执行差错检测?这种重复检测有几种原因:首先,注意到在 IP 层只对 IP 首部计算了检验和,而 TCP/UDP 检验和是对整个 TCP/UDP 报文段进行的。其次,TCP/UDP 与 IP 不一定都必须属于同一个协议栈,原则上,TCP 能够运行在一个不同的协议(如 ATM)上,而 IP 能够携带不一定要传递给 TCP/UDP 的数据
- IP 数据报传输 TCP 段和 UDP 段的头部:
- TCP:20 bytes of IP + 20 bytes of TCP + data = 40 bytes + data
- UDP:20 bytes of IP + 8 bytes of UDP + data = 28 bytes + data
IPv4 数据报分片
一个链路层帧能承载的最大数据量叫作最大传送单元(Maximum Transmission Unit,MTU),发送方与目的地路径上的每段链路可能使用不同的链路层协议,且每种协议可能具有不同的 MTU ,因此大的 IP 数据报在网络上会被分为片(fragment)
- 相同的 ID
- 不同的偏移量
- 最后一个分片标记为 0
举个🌰
一个 4000 bytes 的数据报需要传输,MTU 为 1500 bytes
4000 bytes of datagram = 20 bytes of IP head + 3980 data
- 第一片:
20 bytes of IP head + 1480 bytes data , offset = 0
- 第二片:
20 bytes of IP head + 1480 bytes data , offset = 1480 / 8 = 185
- 第三片:
20 bytes of IP head + 1020 bytes data , offset = 2960 / 8 = 370
- 由于 IP 是一种不可靠的服务,一个或多个片可能永远到达不了目的地,为了让目的主机绝对地相信它以及收到了初始数据报的最后一个片,最后一个片的标志比特被设为 0 ,而所有其他片的标志比特被设为 1 。
- 为了让目的主机确定是否丢失了一个片且能按正确的顺序重新组装片,使用偏移字段指定该片应放在初始 IP 数据报的哪个位置。
- “重组”只在最终的目的主机进行
- IP 头部的信息被用于标识、排序相关分片
IPv4 编址
IP 地址
IP 要求每台主机和路由器接口拥有自己的 IP 地址,每个 IP 地址长度为 32 比特(等价为 4 字节),因此总共有 232 个(或大约 40 亿个)可能的 IP 地址,这些地址通常按点分十进制记法书写。
例如 11000001 00100000 11011000 00001001 的点分十进制记法为 193.32.216.9
此外,IP 地址又分为子网部分(高位 bits)和主机部分(低位 bits),一个子网内的节点(主机或路由器)它们的 IP 地址的高位部分相同,这些节点构成的网络的一部分叫做子网。
例如 IP 编制为一个子网分配一个地址 233.1.1.0/24 ,其中的 /24 记法有时称为子网掩码(subnet mask),指示 32 比特中的最左侧 24 比特定义了子网地址,因此子网 223.1.1.0/24 由 3 个主机接口(223.1.1.1、223.1.1.2、223.1.1.3)和 1 个路由器接口(223.1.1.4)组成。
特殊的 IP 地址(一些约定):
- 子网部分:全为 0 ——本网层
- 主机部分:全为 0 ——本主机
- 主机部分:全为 1 ——广播地址,这个网络的所有主机
无类域间路由
因特网的地址分配策略被称为无类别域间路由选择(Classless Interdomain Routing, CIDR),CIDR 将子网寻址的概念一般化了,当使用子网寻址时,32 比特的 IP 地址被划分为两部分
如何分配到一个地址:
- 互联网服务提供商(Internet Service Provider,ISP)通过因特网名字和编号分配机构(Internet Corporation for Assigned Names and Numbers,ICANN)获得一个地址块
ICANN 的工作
- 分配地址
- 管理 DNS 根服务器
- 分配域名,解决冲突
- 设备从 ISP 获得的地址块中分配一个小地址块
- 系统管理员将地址配置在一个文件中
Wintel:control panel -> network -> configuration -> tcp/ip -> properties
Unix:/etc/rc.config
- 动态主机配置协议(Dynamic Host Configuration, DHCP)从服务器中动态获得一个 IP 地址,DHCP 返回
- IP 地址
- 第一跳路由器的 IP 地址
- DNS 服务器的域名和 IP 地址
- 子网掩码(指示地址部分的网络号和主机号)
由于 DHCP 具有将主机连接进一个网络的网络相关方面的自动能力,故它又被称为即插即用协议(plug-and-play protocal)或零配置协议(zeroconf)
网络地址转换
NAT
-
实现 NAT 的动机:本地网络只有一个有效 IP 地址
- 不需要从 ISP 分配一块地址,可用一个 IP 地址用于所有的(局域网)设备,达到高效省钱
- 可以在局域网改变设备的地址情况下而无需通知外界
- 可以改变 ISP(地址变化)而不需要改变内部设备的地址
- 局域网内部的设备没有明确的地址,对外是不可见的,可以保证安全性
-
实现 NAT 对于路由器的要求
- 将源地址和端口号替换为 NAT IP 地址和新的端口号,目标的 IP 与端口不变;远端的 c/s 将会用 NAT IP 地址,新端口号作为目标地址
- 记住 NAT 转换表中的每个转换对,源 IP + 端口 = NAT IP + 新端口
NAT 的现实场景
举个🌰
- 主机 10.0.0.1 发送数据报到 128.119.40.186:80
- NAT 路由器根据转换表将数据报源地址、端口号从 10.0.0.1:3345 更新为 138.76.29.7:5001
- 响应返回目标地址 138.76.29.7:5001
- NAT 路由器根据转换表将 IP 地址和端口号更新为 10.0.0.1:3345
对于 NAT 的争议
- 路由器只应该对网络层做信息处理,而 NAT 路由器对端口号(传输层)做了处理
- 违反了 end-to-end 原则
- 端到端原则:复杂性放到网络边缘,无需借助中转和变换就可以直接传送到目标主机
- NAT 可能要被一些应用设计者考虑(P2P applications)
- 外网的机器无法主动连接到内网上
- 地址短缺的问题可以被 IPv6 解决
- 穿越问题
NAT 穿越
穿越问题:客户端需要连接地址为 10.0.0.1 的服务器,但客户端不能够使用其作为目标地址,整个网络只有一个外部可见地址:138.76.29.7
解决方案:
- 静态配置 NAT
- 对转发进来的对服务器特定端口的连接请求进行配置,如 123.76.29.7:2500 总是转发到 10.0.0.1:25000
- 中继(used in Skype)
- NAT 后面的服务器建立和中继的连接
- 外部的客户端连接到中继
- 中继在两个连接之间桥接
- Universal Plug and Play(UPnP)、Internet Gateway Device(IGD)协议允许 NAT 主机可以:
- 获知网络的公共 IP 地址
- 列举存在的缺口映射
- 增/删端口映射(在租用时间内)
IPv6
IPv6 数据报格式
- 版本:占 4 比特,标识 IP 协议的版本号
- 流量类型:占 8 比特,与 IPv4 的服务类型字段类似
- 流标签:占 20 比特,标识一条数据报的流
- 有效载荷长度:占 16 比特,给出了 IPv6 数据报中跟在定长的 40 字节数据报首部后面的字节数量
- 下一个首部:与 IPv4 的上层协议字段类似
- 跳限制:TTL
- 源地址和目的地址:各为 128 比特
- 数据:有效载荷
IPv6 与 IPv4
IPv6 的动机:
- 32 bit 地址空间快要被用完了
- 头部格式改变帮助处理加速和转发
- 头部格式改变帮助 QoS
IPv6 对比 IPv4 的变化:
- checksum:校验和被移除,降低在每一段中的处理速度
- options:在头部之外,被“下一个首部”标识,确保 IPv6 的头部为定长的 40 字节
- ICMPv6:ICMP 的新版本附加了报文类型和多播组管理功能,不允许在中间路由器上进行分片和重新组装
IPv4 暂时还无法完全迁移到 IPv6 ,在数据传输时有可能同时用到 IPv4 和 IPv6 的路由器,这时需要建立隧道帮助两者通信。借助于隧道,在隧道发送端的 IPv6 节点可将整个 IPv6 数据报放到一个 IPv4 数据报的数据(有效载荷)字段中,即在 IPv4 路由器之间传输的 IPv4 数据报中携带 IPv6 数据报。