问题聚焦:
IP协议是TCP/IP协议族的核心协议,也是socket网络编程的基础之一。这里从两个方面较为深入地探讨IP协议:
1,IP头部信息(指定IP通信的源端IP地址,目的端IP地址,指导IP分片和重组,和指定部分通信行为);2,IP数据包的路由和转发(发生在除目标机器之外的所有主机和路由器上)。
1 特点
TCP/IP协议族的动力,为上层协议提供无状态,无连接,不可靠的服务
无状态:IP通信双方不同步传输数据的状态信息,因此IP数据包的发送、传输和接收都是无序的。
缺点:无序,不可靠
优点:简单、高效
不可靠:不能保证IP数据报准确地到达接收端,它只是承诺尽最大努力。发送端(转发端)一旦检测到IP数据包发送失败(如存活时间过长,数据报不正确),就通知上层协议发送失败,而不会试图重传。
因此使用IP服务的上层协议(如TCP协议)需要自己实现数据确认,超时重传等机制以达到可靠传输的目的
2 IPV4头部结构
长度:通常为20字节。
结构:
字段解析:
- 4位版本号:指定IP协议的版本,值为4。
- 4位头部长度:标识该IP头部有多少个32bit(4字节)。IP头部最长是60字节。
- 8位服务类型(TOS):包括3位优先权字段,4位TOS字段(只有一位能置1,分别表示最小延迟、最大吞吐量、最高可靠性、最小费用),和1位保留字段(必须置0)。
- 16位总长度:指整个IP数据报的长度,以字节为单位,因此IP数据包的最大长度为65535。但由于MTU的限制,长度远超MTU的数据报都将被分片传输。
- 16位标识:唯一地标识主机发送的每一个数据报。同一个数据报的所有分片都具有相同的标识值。
- 3位标志字段:第一位保留,第二位"禁止分片"(超过MTU即被丢弃),第三位"更多分片",除了数据包的最后一个分片外,其他分片都要把它置1。
- 13位分片偏移:分片相对原始IP数据报开始处的偏移。实际的偏移值是该值左移3位(乘8)后得到的,由于这个原因,每个IP分片的数据部分的长度必须是8的整数倍。
- 8位生存时间(TTL):是数据报到达目的地之前允许经过的路由器跳数。发送端设置,经过一个路由器,该值就被减一,减为0则丢弃,返回一个ICMP差错报文。防止路由循环。
- 8位协议:用来区分上层协议。ICMP:1;TCP:6;UDP:17。
- 16位头部检验和:发送端填充,接收端对其使用CRC算法以检验IP数据报头部在传输过程中是否损坏。
- 32位源端IP地址和目的端IP地址:标识数据报的发送端和接收端。
- 可选字段:最长40字节,包括记录路由,时间戳,松散源路由选择,严格源路由选择。
数据报Demo分析:
字段解析:
十六机制数 | 十进制表示 | IP头部信息 |
0x4 | 4 | IP版本号 |
0x5 | 5 | 头部长度为5个4字节,即20字节 |
0x10 | TOS字段分别为1000,表示最小延迟开启 | |
0x003c | 60 | IP数据报总长度为60 |
0xa5d5 | 数据报的唯一标识 | |
0x4 | 禁止分片 | |
0x000 | 分片位移 | |
0x40 | 64 | 生存时间为64跳 |
0x06 | 6 | 协议类型:TCP协议 |
0x96cf | 头部校验和 | |
0x7f000001 | 两个:分别表示源主机地址和目的主机地址 |
这个报是使用telnet远程登陆时抓去的,由此可见,telnet使用的是最小延时服务,默认使用传输层协议是TCP协议。IP数据报没有分片,因为没有携带任何应用程序数据。
3 IP分片
分片原因:IP数据报的长度超过帧的MTU,将被分片传输
分片时机:可能发生在发送端,也可能发生在中转路由器上,而且可能在传输过程中被多次分片
重组时机:目标机器的内核的IP模块
分片和重组的信息:数据报标识,标志和片偏移。
MTU:以太网的MTU是1500字节。IP数据报的数据部分最多是1480字节。
下图表示一个数据长度为1481字节的ICMP报文被分片后的结果。
4 IP路由
地位:核心任务
作用:决定发送数据报到目标机器的路径。
IP模块工作流程:由下图分析
从右向左分析:
- IP模块接收到来自数据链路层的IP数据报
- 对数据报头部做CRC校验
- 查看是否是发给本机
- 如果是发给本机则转交给上层应用
- 如果不是则转交给"数据报转发子模块"
- 如果不允许转发,则丢弃;允许转发则一些操作后交给"IP数据报输出子模块"
- 更新路由表,"计算下一跳路由"子模块计算下一跳路由
- 交给IP输出队列
路由表
在机器上执行route命令,可以查看路由表,下面分析一个路由表实例
该路由表有两个记录,每个记录都有8个字段,现在分析一下这个路由表的八个字段的含义:
字段 | 含义 |
Destination | 目标网络或主机 |
Gateway | 网关地址,*表示目标和本机在同一个网络,不需要路由 |
Genmask | 网络掩码 |
Flags |
路由项状态标志: U: 活动的 H:目标是一台主机 G:目标是网关 D:重定向生成的 M:重定向修改过 |
Metric | 路由距离,即达到指定网络所需的中转数 |
Ref | 路由项被引用的次数 |
Use | 被使用的次数 |
Iface | 该路由项对应的输出网卡接口 |
由上边可以判断,demo中的第一个记录的目标地址是default,即所谓的默认路由项。在Flags字段,有一个G标志,说明路由的下一跳地址是网关,其地址是192.168.1.1。
第二条记录中,目标地址是192.168.1.0,指的是本地局域网。该路由项的网关地址为*,,说明数据报不需要路由中转,可以直接发送到目标机器。
IP路由机制:
路由表中的IP匹配分为三个步骤:
- 查找路由表中和路由报的目标IP地址完全匹配的主机IP地址。如果找到,就使用该路由项,没有找到则转步骤2
- 查找路由表中和数据报的目标IP地址具有相同网络ID的网络IP地址,如果找到,则使用该路由项,没有找到则转步骤3
- 选择默认路由项,这通常意味着数据报的下一跳路由是网关
路由表更新:
动态路由更新协议:BGP(边际网关协议),RIP(路由信息协议),OSPF协议
5 IP转发
数据报转发子模块对期望转发的数据报执行如下操作:
- 检查数据报头部的TTL值,如果TTL值已经是0,则丢弃该数据报
- 查看数据报头部的严格源路由选择项,如果该选项被设置,则检测数据报的目标IP地址是否是本机的某个IP地址,如果不是,则发送一个ICMP源站选路失败报文给发送端
- 如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的下一跳路由器
- 将TTL值减1
- 处理IP头部选项
- 如果有必要,则执行IP分片操作
6 重定向
ICMP重定向报文
格式
ICMP重定向报文的类是是5
代码字段有4个可选值,用来区分不同的重定向类型,这里仅讨论主机重定向,其代码值为1
数据部分:提供引起重定向的IP数据报的源端IP地址;应该使用的路由器的IP地址
一般来说,主机只能接收ICMP重定向报文,路由器只能发送ICMP重定向报文
以一个实例作为重定向小结:
手动将机器ernest-laptop的网关设置成机器Kongming20
当ernest-laptop发送IP数据报给Kongming20时,Kongming20会将数据报转发给路由器
并且回一个ICMP数据报给ernest-laptop,告诉他后面的数据报直接发给路由器吧,那条路更好。
参考资料:
《Linux高性能服务器编程》