IP协议是TCP/IP协议族中至关重要的协议,同时也是socker网络编程的基础之一。其中最重要的部分为
(1)ip头部信息:ip头部信息出现在每个ip报文数据报中,用于指定ip通信的远端ip地址,目的端ip地址,指导ip分片和重组,以及部分的通信行为。
(2)ip数据报的路由和转发:ip数据报文的路由和转发发生在除目标机器之外的所有主机和路由器上。他们决定数据包是否应该转发以及如何转发。
1.IP服务特点
ip协议是TCP/IP协议族的动力,为上层协议提供无状态,无连接,不可靠的服务。
无状态:指的是IP通信双方不同步传输数据的状态信息,因此所有IP数据报的发送,传输和接收都是相互独立,没有上下文关系的。这种服务最大缺点就是无法处理重复,乱序的这些情况。乱序:是第n个数据报比第n+1个后到接收端;重复:是同一个数据报通过不同路径多次到达接收端。这些情况ip端无法进行检测,因为这些数据之间没有上下文关系。接收端的iP模块只要接受的完整的IP数据报就将它交给传输层,所以上层协议的角度看这些数据就可能是乱序的,重复的。对于面向连接的协议比如说TCP协议可以自己处理乱序和重复的问题,然后经过TCP协议处理的数据交给上层肯定是有序的,正确的。但无状态也是有优点的:简单,高效。我们不需要为保持通信的状态而分配一些内核资源,也不需要传输数据时携带状态信息。
无连接:IP通信双方都不长久地维持对方仍和信息。所以每次发送数据的时候都必须指定对方的IP地址。
不可靠:IP协议不能保证IP数据报准确的到达接收端,它只是尽可能的保证发送过去,,很多时候可能导致IP数据报发送失败,比如某个中转路由器发现IP数据报在网络存活时间太长就将其丢弃,并返回一个ICMP错误信息给发送端,接收端发现IP数据报不正确也会将其丢弃同时返回一个ICMP错误信息。无论是什么情况,发送端的iP模块检测到错误不会进行重传只会告诉传输层,传输层的协议比如TCP会自己实现数据确认,超时重传达到可靠的目的。
2.IPV4头部结构(长度通常为20字节)
4位版本号:一般为4,代表着ipv4
4位头部长度:标识头部有多少字节
8位服务类型:包括3位优先字段(忽略),4位TOS字段:最小延时,最大吞吐量,最高可靠性,最小费用。这四个中最多只能把一个置为1。比如远程登录就要最小延时,文件传输就要最大吞吐量。
16位总长度:代表整个IP数据报的长度,以字节位单位,16位的最大长度就是2^16-1字节,但是一般都达不到,因为被MTU(最大传输单元)限制。超过MTU的就要分片传输处理,所以接下来就要说如何分片了。
16位标识:唯一标识主机发送的数据报,初始值由系统给定,随后每发一个数据报值就加1,当进行数据报分片时,属于同一个数据报的标识值就相同。
3位标志:第一位字段保留,第二位代表禁止分片,如果设置了这个位那么IP模块就不会对数据报进行分片,如果这时候超过MTU的话IP模块就丢弃这个数据报并返回一个ICMP查重报文。第三位表示更多分片,就是在分片时除了最后一个分片外其余所有分片置为1。
13位片位移:相对于原始IP数据报开始处偏移,原始的偏移值为0,接下来每一个偏移值是上一个数据报的长度。
8位生成时间:数据到达目的地运行通过路由器的最大跳数,一般是64,每通过一次路由器该值减一,当值位0时将数据丢弃代表陷入了路由循环。
8位协议:区分传输层协议,ICMP是1,TCP是6,UDP是17。
16位头部校验和:发送端进行填充,接收方通过CRC算法检验头部是否被损坏。
32位源端ip和目的ip就没什么说的了,大家都懂。
后面还有可变长的可选信息,一般不用,最多占40字节。
下图是抓包得到了头部信息,大家注意看黄线部分的解读。
这是黄线部分的解读:
3.关于IP分片
前面说当数据报的长度超过MTU(最大传输单元)就会进行分片传输,分片可能发布在发送端,也可能发生在中间路由器,可能过程中多次被分片,但只有在到达目的后才进行重组,重组完成以后才会交给上层协议。
上边也说了:数据报标识,标志,位偏移都是为了分片而设计的。一个数据报的每个分片都有自己的IP头部,同属于一个数据报的分片具有相同的标识,但是为偏移不同,同时除了最后一个分片外,其它分片都设置了MF标志。此外每个分片IP头部总长度设置为该分片的长度。
以太网帧的MTU(最大传输单元)是1500字节(netstat和ifconfig可以查询),但是头部长20字节(不附加的情况),所以数据长度最长就是1480字节。所以如果现在有一个长度为1481字节的ICMP数据文,超过了1480所以就要进行分片。第一个分片就是1500字节(20字节IP报头,1480的数据部分,在这1480里的数据部分中包含:8字节的ICMP报头和1472字节的数据),同时在IP头部设置MF标识,代表后续还有分片;第二个IP长度为21字节(20字节的IP的报头,1字节的数据部分,不设置ICMP头部,因为重组的时候不需要重复的ICMP头部信息),同时不设置MF标识,因为是最后一个分片了。
大家认真看上段话和下面这幅图进行对应:
最后IP层传递给数据链路层的数据可能是一个完整的IP数据报,也可能是IP分片。统称为IP分组。
4.IP路由
IP协议的一个核心任务就是数据报的路由,就是发送数据报到目标机器的路径。大家可以先看下面的模块来理解IP模块的工作流程。
过程是这样的:IP数据报先进入IP输入队列进行CRC校验看是否数据报是否受损。确认以后开始处理头部信息,如果IP数据报头部的目标IP是本机的某个IP地址,那么就代表该数据报是发往本机的,则IP模块就根据数据报的头部协议字段看是TCP还是UDP还是ICMP,然后交给上层处理。如果发现这个数据报不是发给本机的,则调用数据报转发模块进行数据转发。一般来说主机只进行发送和接收,路由才能进行转发服务。我们也可以通过修改主机中的参数让主机具备转发功能(/proc/sys/net/ipv4/ip_forward设置为1)。言归正传,到了数据报转发模块检测当前主机是否允许转发,不允许就直接丢弃,允许转发那就进行如下操作:
1.检查数据报头部的TTL值,如果TTL值已经是0,那就丢弃数据报(说明陷入路由循环)。
2.查看数据报的严格路由选项是否被设置(设置以后就必须到那个指定路由器),然后看当前主机是否是被指定的路由器,如果不是那就发送一个ICMP选路失败报文给发送端。
3.将TTL值减1;
4.处理IP头部选项。
5.有必要的话执行分片。
通过数据报转发模块以后就进入了路由模块,因为要转发到下一个路由器,总不能就必须有所依据不能想发哪就发哪吧。这个依据就是路由表,也是IP模块的核心数据结构。这个表按照数据报的IP地址进行分类,同一类型的IP数据报将被发往相同的下一跳路由器。这个路由模块不仅会转发,还要执行本机上的数据发送。
要说路由机制那就先要理解路由表,我们通常使用route或者netstat命令查看路由表。
在表2-2中,第一行的目标地址是default,就是默认路由项,后面flag中包含了G代表下一跳是网关。网关的存在支持用户使用因特网。
第二行中目标地址是192.168.1.0,网关地址是 * ,代表是本地局域网内,说明数据报不需要路由中转,可以直接发送到目标机器。
那么核心问题来了:现在根据IP数据报的头部知道了目标的IP地址,现在匹配路由表中的哪一项呢?这就是常说的IP路由机制
(1)查找路由表中和数据报的目标IP地址完全匹配的主机IP地址。如果找到那就使用该路由项。没找到就看下一项。
(2)查找路由表中和数据报的目标IP地址具有相同网路的IP地址(就比如192.168.1.1和192.168.1.0就是相同网路)。如果找到
就使用,没找到就看下一项。
(3)选择默认路由项,意味着发送到了网关。
关于路由还有一个核心就是路由表更新
路由表必须能够更新,这样IP模块才能准确高效准发数据报。路由表更新分为静态更新和动态更新。静态更新就是人为手动更新,动态更新就是通过BGP,RIP,OSPF等协议发现路径并且更新自己的路由表。现在就稍微说一下静态更新路由表
第一行就是增加了一个主机
第二行就是删除网络号为192.168.1.0,子网掩码是255.255.255.0的主机
第三行删除默认路由。//删除了就无法访问因特网,因为下一跳是网关
第四行就是把192.168.1.109设置为默认路由项,但网关不是可以直接访问因特网的路由器。
路由器这部分在面试的时候基本不怎么被问到,所以大致了解就好。
以上就是IP模块的全部内容。欢迎大家指正。