IP 协议
IP 协议
IPv4
数据报格式
数据报首部信息(通常为20byte):
- 版本(4bit) - 规定数据报的IP协议版本
- 首部长度(4bit) - 大多数IP数据报不包含选项,一般的IP数据报具有20byte的首部
- 服务类型(8bit) - 区别不同类型的数据报,现在不太用
- 数据报长度(16bit) - IP数据报的总长度
- 标识号(16bit) - 标识属于同一原始数据报的片
- 标志(3bit) - 标识当前片是否为原始数据报的最后一片
- 片位移(13bit) - 指定该片在原始数据报中的位置
- 寿命(TTL)(8bit) - 每当一台路由器处理数据报时,该字段的值减1,为0则丢弃该数据报
- 协议(8bit) - 指示了IP数据报的数据部分应交给哪个特定的传输层协议
- 首部检验和(16bit) - 同 UDP checksum
- 源IP地址(32bit)
- 目标IP地址(32bit)
- 选项 - 允许IP首部被扩展
分片
一个链路层帧能承载的最大数据量叫作最大传送单元(Maximum Transmission Unit, MTU)
在发送方与目的地路径上的每段链路可能使用不同的链路层协议,且每种协议可能具有不同的 MTU,因此 IPv4协议下,当 IP 数据报大小大于 MTU 时,将 IP 数据报中的数据分片成两个或更多个较小的 IP 数据报,用单独的链路层帧封装这些片(fragment)
发送主机在生成数据报时通过标识号区分每个数据报,路由器分片时令每片的标识号与源数据报相同,以使目标主机确认哪些数据报是同一原始较大数据报的片
分片时最后一片的标志设为0,其他片标志设为1,以使目标主机确认收到了全部的源数据报
片位移字段用于指定每片在原始数据报中的位置
分片传输中,一旦某个分片丢失,则会造成整个 IP 数据报作废,所以 TCP 引入了 MSS,在 TCP 层提前进行分片,对于 UDP 应尽量控制不发送一个大于 MTU 的数据报文
IP地址
主机/路由器和物理链路的连接处叫作接口(interface),一个 IP 地址与一个接口而非主机或路由器相关联
每个 IPV4 地址长度为32bits(4bytes),因此总共有2^32个(大约40亿)可能的 IPV4 地址
IP 地址通常按点分十进制记法书写,即地址中的每个字节用十进制形式书写,各字节间以 . 隔开
子网
将主机和路由器中接口间的连接断开所产生相互隔离的网络岛称为子网(subnet),一个接口的 IP 地址的一部分由其连接的子网决定
子网划分实际上是将主机地址分为两个部分:子网网络地址和子网主机地址
- 未做子网划分的 ip 地址:网络地址 + 主机地址
- 做子网划分后的 ip 地址:网络地址 + (子网网络地址 + 子网主机地址)
子网掩码同样为32bit,通过将对应位置 bit 置1表示子网 IP 地址中的该位表示子网部分,将子网掩码和 IP 地址按位与计算,就可得到子网网络地址
分类编址
IP 地址过去采用分类编址,现在采用无类别域间路由选择CIDR
分类编址架构中,IP 地址分为 ABCDE 五类

原始的A、B、C类网络的子网掩码分别为:
- A - 255.0.0.0 - 11111111 00000000 0000000 00000000
- B - 255.255.0.0 - 11111111 11111111 0000000 00000000
- C - 255.255.255.0 - 11111111 11111111 11111111 00000000
- D 类为多播地址
- E 类为预留地址
所有 IP 地址的头部为分类号,A、B、C 类地址的剩余部分又分为网络号和主机号
特殊 IP 地址
- 主机号全为0 - 指定本网络
- 主机号全为1 - 广播地址,指定本网络的所有主机
127.0.0.1- 回环地址,访问自身localhost- 域名,默认被解析为127.0.0.1127.X.X.X- 保留地址,目前并没有被规定和分配给任何特定的用途0.0.0.0- 无效的目标地址,但listen 0.0.0.0表示监听本机上的所有 ipv4 地址
还有一些私有地址,仅供专用地址使用,不会被当做公用地址来分配,只在局部网络中用于区分不同的设备,路由器不对目标地址是私有地址的分组进行转发:
- A - 10.0.0.0-10.255.255.255
- B - 172.16.0.0-172.31.255.255
- C - 192.168.0.0-192.168.255.255
多播用于将包发送给特定组内的所有主机
从 224.0.0.0 ~ 239.255.255.255 都是多播的可用范围,其划分为以下三类:
- 224.0.0.0 ~ 224.0.0.255 为预留的组播地址,只能在局域网中,路由器不进行转发
- 224.0.1.0 ~ 238.255.255.255 为全球范围内多播应用程序所分配的组播地址,可供组织使用。其中 224.0.1.0 保留用于向所有多播互联网主机传送多播包
- 239.0.0.0 ~ 239.255.255.255 为本地管理组播地址,可供内部网在内部使用,仅在特定的本地范围内有效
分类编制缺陷:
- 同一网络下没有地址层次
- 主机数不能很好的与现实网络匹配
CIDR
现在互联网的地址分配策略被称为无类别域间路由选择(Classless Inlerdomain Routing,CIDR)
该策略下没有分类号,IP 地址仅被分为网络号和主机号
地址格式: a.b.c.d/x,其中 x 代表 IP 地址中网络号的长度
ISP 从因特网名字和编号分配机构 ICANN 获取 IP 地址块
网络管理员从 ISP 获得地址块中分配一个小地址块用于子网
主机可通过系统管理员手动配置或动态主机配置协议 DHCP 自动获取 IP 地址以及子网掩码、第一跳路由器地址(常称为默认网关)、本地 DNS 服务器的地址等其他常用信息
IP 发包
- 源 IP 与目标 IP 处于一个子网(源主机 IP 地址&子网掩码 == 目标主机 IP 地址&子网掩码),直接将包通过交换机发出去
- 源 IP 与目标 IP 所属子网不同,源主机将包发给默认网关(路由器),之后路由器通过路由表确定转发端口,将包转发至其他路由器,最终到达目标子网,进而到达目标主机
IPv6
IPv6用于解决32比特的 IP 地址空间被用尽以及 IPv4中存在的一些问题
数据报格式
IPv6数据报首部(固定40 byte):
- 版本(4 bit) - 规定数据报的 IP 协议版本
- 流标签(20 bit) - 给属于特殊流的分组加上标签,准备用于服务质量控制
- 流量类型(8 bit) - 区别不同类型的数据报
- 有效载荷长度(16 bit) - IP 数据报主体的长度
- 跳限制(TTL)(8 bit) - 每当一台路由器处理数据报时,该字段的值减1,为0则丢弃该数据报
- 下一个首部(8 bit) - 指示了 IP 数据报的数据部分应交给哪个特定的传输层协议,可指定选项
- 源 IP 地址(128 bit)
- 目标 IP 地址(128 bit)
IPv6 相比 IPv4 的首部改进:
- 取消了首部校验和字段 - 因为在数据链路层和传输层都会校验,因此 IPv6 直接取消了 IP 的校验
- 取消了分片/重新组装相关字段 - IPv6不允许在中间路由器上进行分片与重新组装,这种操作只能在源与目的地执行,IPV6通过 PMTU 协议来实现链路上最小的 MTU 发现,从而实现端到端的通信以及提升报文的转发效率
- 取消选项字段 - IPv6 的首部为固定长度的 40 字节,选项字段没有完全去除,其可能出现在 IPv6 首部中的
下一个首部指出的位置上
首先源节点假设PMTU就是其出接口的MTU,发出一个试探性的报文,当转发路径上存在一个小于当前假设的PMTU时,转发设备就会向源节点发送Packet Too Big报文,并且携带自己的MTU值,此后源节点将PMTU的假设值更改为新收到的MTU值继续发送报文。如此反复,直到报文到达目的地之后,源节点就能知道到达目的地的PMTU了
地址
IPv6 地址长度是 128 bits,16bits 作为一组,每组用冒号 : 隔开
出现连续的 0 时可以将这些 0 省略,并用两个冒号 :: 隔开,但是一个 IP 地址中只允许出现一次两个连续的冒号
IPv6 地址类型:
- 未定义 -
::/128 - 环回地址 -
::1/128 - 唯一本地地址 -
FC00::/7- 在内网里单播通信,可以使用唯一本地地址,相当于 IPv4 的私有 IP
- 链路本地单播地址 -
FE80::/10- 在同一链路单播通信,不经过路由器,可以使用链路本地单播地址,IPv4 没有此类型
- 多播地址 -
FF00::/8 - 全局单播地址 - 其他
- 在互联网通信,可以使用全局单播地址,相当于 IPv4 的公有 IP
IPV6优点
- 地址空间更大:IPv6地址长度为128位,大大扩展了地址空间
- 更好的安全性:IPv6通过内置的 IPSec 协议提供了更好的加密和认证机制,因此比 IPv4更加安全
- 更好的路由和多播:IPv6的地址结构的设计更简单,路由器比较容易处理,同时IPv6在多播方面有着更好的支持,能够提供更加高效的网络资源利用
- 更好的质量服务(QoS):IPv6中的QoS机制更加完善,能够提供更好的服务质量,保证了实时数据传输的可靠性和效率
隧道
隧道被用于 IPv4到 IPv6 的过渡,IPv6可使用 IPv4隧道进行连接
隧道发送端的 IPv6 节点可将整个 IPv6 数据报封装至一个 IPv4 数据报的数据(有效载荷)字段进行传输
隧道接收端的 IPv6 节点收到该 IPv4 数据报,并确定该 IPv4 数据报含有一个 IPv6 数据报,从中取出 IPv6数据报,然后再为该 IPv6 数据报提供路由
IPv4 数据报将协议号字段(定义于下一首部字段中)设为41指示该 IPv4 有效载荷是 IPv6 数据报
相关协议
DHCP
DHCP又称即插即用协议或零配置协议,当一个新主机连接网络时
- 主机通过255.255.255.255广播 DHCP discover message
- DHCP 服务器用 DHCP offer message 广播提供报文响应
- 主机从一个或多个服务器提供中选择一个,并广播向选中的服务器提供用 DHCP request message 进行响应,回显配置的参数(DHCP offer message 中包含收到的发现报文的事务 ID、向客户推荐的 IP 地址、子网掩码、IP 地址租用期)
- DHCP 服务器使用 DHCP ACK message 广播响应,证实所要求的参数

在最简单场合下,每个子网将具有一台 DHCP 服务器。如果在某子网中没有服务器,则需要一个 DHCP 中继代理(通常是一台路由器),这个代理知道用于该网络的 DHCP 服务器的地址。
使用单个网络前缀通告多个网络的能力通常称为地址聚合,也称为路由聚合或路由摘要
NAT
网络地址转换(Network Address Translation,NAT)被用于解决子网过大(IP 地址不够用)的问题
NAT 路由器对于外部互联网而言如同一个具有单一 IP 地址的单一设备
NAT 路由器收到内网主机发送的数据报后
- 生成一个未使用的端口号 X,将内网 IP 地址及源端口与该端口号绑定,通过NAT 转换表记录该绑定关系
- 使用 NAT 路由器自身 IP 地址以及端口号 X 作为源主机地址和端口,向数据报中的目标主机及目标端口发送
- 将 Web 服务器发回的响应报文通过 NAT 转换表查找后转发至相应的内网主机端口
私有网络一般使用私有地址,RFC1918规定的三类私有地址如下:
- 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)
对于运行在内网中的服务器,NAT 会使得无法从外部向内部服务器建立连接,技术解决方案包括 NAT 穿越(NAT traversal)工具和通用即插即用(Universal Plug and Play, UPnP)
解决方案1:静态配置 NAT,将服务器特定端口与 NAT 端口绑定
解决方案2:内网主机获取 NAT 服务器 IP 地址,动态进行 NAT 端口映射配置(UPnP)
解决方案3:在外部互联网中设置中继点,内网主机建立与中继的连接
ICMP
因特网控制报文协议 ICMP用于主机、路由器、网关传达网络层控制信息
ICMP 主要的功能包括
- 确认 IP 包是否成功送达目标地址
- 报告发送过程中 IP 包被废弃的原因
- 改善网络设置
ICMP 通常被认为是 IP 的一部分,但 ICMP 报文实际基于 IP 协议进行消息传输
ICMP报文包含
- 类型字段 8 bit
- 代码字段 8 bit
- 校验和 16 bit
- 数据内容
ICMP报文类型大致可以分为查询报文类型和差错报文类型两大类
| 类型字段 | 内容 | 种类 |
|---|---|---|
| 0 | 回送应答(Echo Reply) | 查询报文类型 |
| 3 | 目标不可达(Destination Unreachable) | 差错报文类型 |
| 4 | 原点抑制(Source Quench) | 差错报文类型 |
| 5 | 重定向或改变路由(Redirect) | 差错报文类型 |
| 8 | 回送请求(Echo Request) | 查询报文类型 |
| 11 | 超时(Time Exceeded) | 差错报文类型 |
代码字段
0- 网络不可达1- 主机不可达2- 协议不可达3- 端口不可达4-需要分片但未分片
IP 路由器无法将 IP 数据包发送给目标地址时,会给发送端主机返回一个目标不可达的 ICMP 消息,并在 ICMP 包头的代码字段记录不可达的具体原因
ping
ping 是一个应用层命令,其尝试发送一个消息至目标地址以判断目的机器是否可达
ping 底层应用 ICMP 协议
127.0.0.1属于回环地址,localhost是域名,但默认等于127.0.0.1ping回环地址和ping本机 IP 地址都走lo0"假网卡" ,都会经过网络层和数据链路层,加上 IP 头和 MAC 头,但最后"假网卡"会把数据推到input_pkt_queue链表中,软中断通知ksoftirqd内核线程取出消息向上传递给应用程序- 如果服务器
listen的是0.0.0.0,那么此时用127.0.0.1和本机地址都可以访问到服务 - 执行
ping 0.0.0.0会失败,因为0.0.0.0在IPV4中表示无效的目标地址