《TCP/IP详解 卷1》 笔记: IP协议

引言

    IP是TCP/IP协议族中最为核心的协议。IP层提供不可靠、无连接的数据报传输服务。

    不可靠(unreliable)的意思是它不能保证IP数据报能成功地到达目的地。IP仅提供最好的传输服务。如果发生某种错误时,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给源主机。任何要求的可靠性必须由上层来提供(如TCP)。

    无连接(connectionless)的意思是IP并不维护任何关于后续数据报的状态信息。每个数据报的处理是相互独立的。这也说明,IP数据报可以不按发送顺序接收。

IP首部

    IP数据报首部的格式如下:

《TCP/IP详解 卷1》 笔记: IP协议

    4个字节的32位值以下面的次序传输:首先是0~7位,其次8~15位,然后16~23位,最后是24~31位。这种传输次序称作大端字节序(big endian)。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序。相对应的主机上的字节序称为主机字节序。如果主机字节序是小端字节序(little endian)格式,则必须在传输数据之前把首部转换成网络字节序。
    (补充:大端字节序,在内存中一个32位长的整数,低位字节的内存地址是高地址(高地址是相对低地址而言的),高位字节的内存地址是低地址。小端字节序,在内存中一个32位长的整数,高位字节的内存地址是高地址,低位字节的内存地址是低地址。Intel x86架构的CPU字节序都是小端,ARM架构的CPU字节序都是大端。)
    首部长度指的是首部占32位字长的数目,包括任何选项。由于它是一个4位的字段,因此首部最长为60个字节。
    服务类型(TOS)字段包括一个3位的优先权子字段(现在已被忽略),4位的TOS子字段和1位未用位但必须置0。4位的TOS分别代表:最小时延、最大吞吐量、最高可靠性和最小费用。
    总长度字段是指整个IP数据报的长度,以字节为单位。利用首部长度字段和总长度字段,就可以知道IP数据报中数据的起始位置和长度。总长度字段是IP首部中必要的内容,因为一些数据链路(如以太网)需要填充一些数据以达到最小长度。

    标识字段唯一地标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1。

    标志字段和片偏移字段与IP分片相关,后面我们介绍UDP协议时再讨论。

    生存时间TTL(time-to-live)字段设置了数据报可以经过的最多路由器数。它指定了数据报的生存时间。TTL的初始值由源主机设置(通常为32或64),一旦经过一个处理它的路由器,它的值就减去1。当该字段的值为0时,数据报就被丢弃,并发送ICMP报文通知源主机。
    首部检验和字段是根据IP首部计算的检验和码。它不对首部后面的数据进行计算。ICMP、IGMP、UDP和TCP在它们各自的首部中均含有同时覆盖首部和数据检验和码。
    每一份IP数据报都包含源IP地址目的IP地址
    最后一个字段是选项,它是数据报中的一个可变长的可选信息。选项字段以32位作为界限,在必要的时候插入值为0的填充字节。这样就保证IP首部长度始终是32位的整数倍(这是首部长度字段所要求的)。有如下几个选项:
        记录路径(让每个路由器都记下它的IP地址)。
        时间戳(让每个路由器都记下它的IP地址和时间)。
        宽松的源站选路(为数据报指定一系列必须经过的IP地址)。
        严格的源站选路(与宽松的源站选路类似,但是要求只能经过指定的这些地址,不能经过其他的地址)。
    这些选项很少被使用,并非所有的主机和路由器都支持这些选项。
IP路由选择
    如果目的主机与源主机直接相连(如点对点链路)或都在一个共享网络上(如以太网),那么IP数据报就直接送到目的主机上。否则,主机把数据报发往一默认的路由器上,由路由器来转发该数据报。大多数的主机都是采用这种简单机制。
    IP层既可以配置成路由器的功能,也可以配置成主机的功能。本质上的区别在于主机从不把数据报从一个接口转发到另一个接口,而路由器则要转发数据报。

    IP层在内存中有一个路由表。当收到一份数据报并进行发送时,它都要对该表搜索一次。当数据报来自某个网络接口时,IP首先检查目的IP地址是否为本机的IP地址之一或者IP广播地址。如果是这样,数据报就被送到由IP首部协议字段所指定的协议模块进行处理。如果数据报的目的不是这些地址,那么(1)如果IP层被设置为路由器的功能且能找到路由,那么就对数据报进行转发;否则(2)数据报被丢弃。

    路由器上的IP路由选择功能按如下步骤工作:
        1. 搜索路由表,寻找能与目的IP地址完全匹配的表项(网络号和主机号都要匹配)。如果找到,则把报文发送给该表目指定的下一跳路由器或直接连接的网络接口(取决于标志字段的值)。
        2. 搜索路由表,寻找能与目的网络号相匹配的表项。如果找到,则把报文发送给该表项指定的下一跳路由器或直接连接的网络接口(取决于标志字段的值)。目的网络上的所有主机都可以通过这个表项来处置。例如,一个以太网上的所有主机都是通过这种表项进行寻址的。这种搜索网络的匹配方法必须考虑可能的子网掩码。
        3. 搜索路由表,寻找标为“默认(default)”的表项。如果找到,则把报文发送给该表项指定的下一跳路由器。如果找不到,则丢弃数据报,给源主机返回一个ICMP错误。

路由表

    路由表中的每一项都包含下面这些信息:
        1. 目的IP地址。它既可以是一个完整的主机地址,也可以是一个网络地址,由该表目中的标志字段来指定。
        2. 下一跳路由器(next-hop router)的IP地址或者一个外出接口的IP地址。下一跳路由器是指一个在直接相连网络上的路由器,通过它可以转发数据报。下一跳路由器不是最终的目的,但是它可以把传送给它的数据报转发到最终目的。
        3. 标志。其中一个标志指明目的IP地址是网络地址还是主机地址,另一个标志指明第2点中提到的IP地址是下一跳路由器IP地址还是一个外出接口IP地址。
        4. 一个网络接口。数据报从这个接口被转发出去。
子网寻址

    现在所有的主机都要求支持子网编址(RFC950)。不是把IP地址看成由单纯的一个网络号和一个主机号组成,而是把主机号再划分成一个子网号和一个主机号。B类地址的一种子网编码如下:

《TCP/IP详解 卷1》 笔记: IP协议

子网掩码

    除了IP地址以外,主机还需要知道有多少位用于子网号及多少位用于主机号。这是通过子网掩码来确定的。这个掩码是一个32位的值,其中值为1的位留给网络号和子网号,为0的位留给主机号。下图给出了一个B类地址使用不同的子网掩码划分的例子:
《TCP/IP详解 卷1》 笔记: IP协议
    尽管IP地址一般以点分十进制方法表示,但是子网掩码却经常用十六进制来表示,特别是当界限不是一个字节时。比如上图中第一个子网掩码是24位,第二个子网掩码是26位。

    给定IP地址和子网掩码以后,主机就可以确定IP数据报的目的是:(1)本子网上的主机;(2)本网络中其他子网中的主机;(3)其他网络上的主机。

特殊情况的IP地址

    经过子网划分的描述,现在介绍7个特殊的IP地址,如下图所示:

《TCP/IP详解 卷1》 笔记: IP协议

    在这个图中,0表示所有的比特位全为0。-1表示所有的比特位全为1。netid、subnetid和hostid分别表示不为全0或全1的对应字段。子网号栏为空表示该地址没有进行子网划分。

    表的头两项是特殊的源地址,中间项是特殊的环回地址,最后四项是广播地址。