IP协议是TCP/IP协议族中最核心的协议,所有的TCP,UDP、ICMP以及IGMP等协议都以IP数据报的格式传输。IP协议提供最好的传输服务,其提供无连接、不可靠的数据传输。或许这句话读起来很矛盾,为什么说是最好的传输服务,但同时又是不可靠的呢。
最好的传输可以认为IP协议会尽一切能力到达目的主机,若中途发生错误无法到达目的主机,也会返回一个ICMP错误报文。收到IP协议返回的错误报文后,本机就知道报文没有成功到达目的主机。而接下来的传输可靠性,即重传,则不属于IP协议的范畴,而是通过TCP协议(或者自己实现的应用层协议)来保证。
不可靠是指即使传输过程中出现错误,IP协议并不负责处理报文重传的工作,而是交给上层协议。
无连接是指IP协议的首部中不保存维护任何关于后续数据报的相关状态信息。
IP数据报的格式如图3-1:
3-1
版本:IP协议的版本号,IPV4即为4
首部长度:包含任意选项,以32位字为单位的长度。由于是一个4比特字段,可知IP首部最长为16*4字节,即64字节
服务类型:包括一个3 bit的优先权子字段(现在已被忽略),4 bit的TOS子字段和1 bit未用位但必须置0。4 bit的TOS分别代表:最小时延、最大吞吐量、最高可靠性和最小费用。4 bit中只能置其中1 bit。如果所有4 bit均为0,那么就意味着是一般服务。
总长度:代表IP数据包的总长(包括其后承载的协议首部与用户数据),由于其有16bit,单位为字节数,可知IP数据报的总长度为65536字节。不过尽管IP首部允许其传输如此大的字节数,以太网封装的链路层也是不允许的,以太网封装的链路层,最大允许承载的IP数据报长度为1500字节。并且主机也要求不能接收超过576字节的数据报。该限制不会影响到TCP协议,因为TCP协议会主动将数据包分段传输。
标识:唯一的标识主机发送的每一份数据报,通常每发送一份数据报就会加1,在IP分片中起到顺序重组的作用。
标志:标志该报文类型,在IP分片中代表该报文是否是分片报文
片偏移:分片报文中指明偏移量
生存时间TTL:设置数据报可以经过的路由跳数,每经过一个路由则减1,减到0仍为到达目的主机则丢弃该报文。可解决黑洞路由,报文一直占用带宽的问题。TTL最大值为255.
协议:即指明IP首部后承载的协议类型,如ICMP/IGMP/TCP/UDP等,前文曾提到该字段。
首部检验和:仅包括IP数据报首部的检验和,检验和的计算不包含其承载的IGMP/ICMP等协议的报文内容。检验和可以检验IP数据报在传输过程中,首部是否出现的错误。RFC 1071包含了如何计算检验和的方法,感兴趣可以了解。
源IP地址:即前文所述的32位互联网地址,代表报文的始发主机。
目的ip地址:代表报文的目的主机。
选项:是一个任选项,可以用作以下领域,但很少被使用。
很少被使用且并不是所有的主机与路由器都实现了这些选项。值得注意的是选项字段必须是32位的整数倍,因为首部长度是32bit的整数倍。若未达到32位的整数倍,可以用0填充。
IP协议提供的最本质的服务之一就是为报文提供选路功能。
IP层的路由功能存在两种模式,一种是路由器模式,一种是主机模式。一般来说,主机是不作为路由器模式使用。
路由器模式与主机模式的本质区别在于系统是否转发从网络口接收进来的报文。若配置为主机模式,则对目的ip非本机的报文,系统做丢弃处理,而路由器则会去查找路由表(提供选路信息的转发表),若查找到则将该报文从对应的网络接口转发出去,转发之前需要更改报文的源目mac地址,且TTL-1(如前文所述,为了防止黑洞路由占用带宽),若TTL被减为0,则做丢弃处理不转发。两种模式对于目的ip属于本机或者为广播地址(广播地址即前文所述的5类互联网地址中主机号为全1的互联网地址)的报文,数据报就被送到由I P首部协议字段所指定的协议模块进行处理。
包含选路信息的路由表中,一般都包含以下这些信息:
目的IP地址:可以是一个主机地址(即全掩码的IP地址,主机号包含非0值,这种称为主机路由),也可以是一个网络地址(即非全掩码的IP地址,主机号为全0,这种称为网络路由)
下一跳路由器的IP地址或直连IP的网络地址:下一跳路由器的IP地址即报文需要转发到的下一个网络接口的IP地址(这个网络接口与当前的路由器直连);而直连IP的网络地址会直接标明该网段IP地址的路由出口,报文直接从该出口转发(前提是该报文的目的IP必须存在,可通过ARP报文探测验证)。
标志:指明路由的类型,例如路由是直连网络地址还是真正的下一跳地址,路由时OSPF协议计算地址还是BGP协议学习地址等。
网络接口:为数据报传输指定一个网络接口。
IP路由选择是逐跳地(hop-by-hop)进行的。从这个路由表信息可以看出,IP并不知道到达任何目的的完整路径(当然,除了那些与主机直接相连的目的)。所有的I P路由选择只为数据报传输提供下一站路由器的IP地址。它假定下一站路由器比发送数据报的主机更接近目的,而且下一站路由器与该主机是直接相连的。
IP路由选择主要完成以下这些功能:
如果上面这些步骤都没有成功,那么该数据报就不能被传送。如果不能传送的数据报来自本机,那么一般会向生成数据报的应用程序返回一个“主机不可达”或“网络不可达”(即IP协议附属ICMP协议报文)的错误。
图3-2,是我在一个路由器查看路由表的结果:
3-2
S代表该路由时静态配置,不是通过协议生成。重点关注标注的三条路由,分别是主机路由、网络路由和默认路由。查表时,优先查找主机路由表,若能匹配中,则报文直接按照查表结果转发。若无法匹配中,则继续查找网络路由表,若匹配中网络路由则按照查表结果转发。若仍无法匹配中,查找是否存在默认路由,存在的话匹配默认路由转发。若所有的都无法匹配中,那么丢弃该报文。
举个例子,一个目的IP是200.1.1.2的报文进来,那么直接命中主机路由表,报文直接按照查表结果,往下一跳网络接口IP为192.168.3.1的路由器转发。若进来的报文目的IP为200.1.1.3,那么无法命中主机路由表,而命中了网络路由表,那么就往下一跳网络接口IP为192.168.4.1的路由器转发。若进来的报文目的IP为100.1.1.2,那么既不能命中主机路由表,也不能命中网络路由表,只能命中默认路由,那么就往下一跳网络接口IP为101.0.0.1的路由器转发.
这里有人可能会疑问,明显主机路由能更精确匹配,直接全部使用主机路由就完事了,为什么还需要网络路由的存在。这里主要考虑的是资源容量问题,硬件资源是有限的,一个路由表不可能无限大,能让你容纳那么多的主机路由。因此,网络路由是很有必要的,网络路由的存在大大缩减了对路由表容量的要求。
值得注意的是,在这个转发过程中,报文中的目的IP地址始终都未修改(使用源路由选项时会修改,但这种情况很少出现),所有的路由决策都是通过这个目的IP来决策。
现在所有的主机都要求支持子网寻址(RFC 950规定)。不再把一个互联网IP地址单纯的认作由网络号与主机号组成,而是将主机号再次进行划分,主机号分为子网号和主机号两部分。这么做的主要好处在于使得互联网地址的使用更加灵活,因为往往一个网络号后是用不了这么多主机的,例如B类的互联网地址,有16位的主机号,即可以包含2^16的主机数量,而往往这一个网络号下不会存在这么多主机,存在极大的浪费。图3-3展示了B类地址的一种子网编址方式。
3-3
这种对B类地址的子网划分是比较典型的划分方法,这种方式在利用点分十进制的方式表示IP地址时,可以很容易的区分子网号和主机号。大部分对互联网地址的划分都是对B类互联网地址的划分,其实对C类地址也是可以划分的,只是C类地址的主机号本身只有8位,可用来划分的位数较少。不止C类地址,A类地址也是经常会被划分。
总结一句,这种划分子网的方式非常灵活,不一定需要8位一个整体的划分,可以通过子网掩码来精确划分到具体的位。例如一个A类地址表示成40.40.40.2/24,那么24就标识前24位属于网络号+子网号,而我们知道A类地址的网络号只有8位,可以知道该地址的网络号为前8位,即40,而子网号有16位,即40.40,主机号为2。掩码有一种经常使用的表示方法,40.40.40.2/24这个也可以等价表示为40.40.40.2 255.255.255.0,其中255.255.255.0就是我们所说的真正的子网掩码。
既然我们已经了解了所谓的IP地址与子网掩码,那么在我们的主机上可以如何查看自己的网络接口所属的IP地址与相应的子网掩码呢。
在unix系统与类unix系统(linux)上可以使用ifconfig命令查看相应的ip地址,图3-4是我在一个linux系统上用命令查看的结果
3-4
可以看到存在多个网络接口,分别分配有B类地址,C类地址与环回地址,其中netmask即子网掩码,可以发现在这台主机上,子网掩码与互联网地址的网络号位数相同。同时可以发现,各个网络接口的MTU最大值为1500(前文链路层所述,以太网接口的IP数据报MTU范围为46-1500),而环回接口的MTU为65536,是IP首部所能承载的最大数据报字节数。这是因为环回接口接收的包是由本机发出,不需经过网络传输(前文TCP/IP简介所述,MTU的限制与传输时延相关),因此可以发最大的IP数据报。
除了ifconfig可以查询本机网络接口的信息,也可以通过netstat -in来查看主机的网络接口与IP地址。
本篇主要讲述了