TCP/IP协议-网络层

风尘

文章目录

  1. 1. 网际协议-IP

[TOC]

网际协议-IP

IPTCP/IP协议族中最为核心的协议。所有TCPUDPICMPIGMP数据都以IP数据报格式传输。

它不能保证IP数据报能成功地到达目的地。 IP仅提供最好的传输服务。如果发生某种错误时,如某个路由器暂时用完了缓冲区, IP有一个简单的错误处理算法:丢弃该数据报,然后发送 ICMP消息报给信源端。

它是无连接的,不维护任何数据报文的后续状态信息。每个数据报相互独立,因此IP数据报可以不按顺序接收。当一个端向另一端发送两个数据报(AB),每个数据报都是独立进行路由选择,可能选择不同线路,所以B可能在A之前到达。

  • IP首部

    IP首部IP首部

    最高位在左边,记为0bit; 最低位在右边,记为31bit

    4个字节的32bit的值以下面次序输出:

    ​ 首先,0~7bit; 其次8~15bit; 然后16~23bit; 最后24~31bit

    TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序(big endian)

    以其他形式存储的二进制整数的机器(如little endian),必须在传输数据之前把首部转换成网络字节序。

    目前协议 版本(Ver) 号是4,因此有时IP也被称为IPv4

    首部长度(IHL) 指的是首部占用32bit的数目,普通IP该字段的值为5行(固定部分),每行 32/8=432/8=4 字节 ,因此首部长度为 54=205*4=20 个字节。如果有选项部分,由于首部长度为4bit,所以最大值为 241=152^4-1=15 行(即取值范围 0-15),所以首部最大长度为 154=6015*4=60 字节。

    服务类型(TOS,Type Of Service),字段包括

    • 一个3bit的优先权子字段(现在已被废弃),默认值000

    • 4bitTOS子字段,分别代表(最小时延、最大吞吐量、最高可靠性、最小费用),只能置其中1bit1,如果均为0,那么就意味着一般服务。

    应用 最小延时 最大吞吐量 最高可靠性 最小费用 16进制值
    Telnet/Rlogin 1 0 0 0 0x10
    FTP
    控制 1 0 0 0 0x10
    数据 0 1 0 0 0x08
    任意块数据 0 1 0 0 0x08
    TFTP 1 0 0 0 0x10
    SMTP
    命令阶段 1 0 0 0 0x10
    数据阶段 0 1 0 0 0x08
    DNS
    UDP查询 1 0 0 0 0x10
    TCP查询 0 0 0 0 0x00
    区域查询 0 1 0 0 0x08
    IMCP
    差错 0 0 0 0 0x00
    查询 0 0 0 0 0x00
    任何IGP 0 0 1 0 0x04
    SNMP 0 0 1 0 0x04
    BOOTP 0 0 0 0 0x00
    NNTP 0 0 0 1 0x02
    • 1bit的未用位(必须置0)

    Telnet/Rlogin应用为例,因为这两个应用主要用于传输少量交互数据,所以要求最小传输时延。其TOS最终值为000,1000,0,换算成十六进制为0x10

    现在大多数TCP/IP实现都不支持TOS特性,但自4.3BSD Reno以后新版本系统都对它进行了设置。另外,新路由协议OSPEIS-IS都能根据这些字段进行路由决策。

    由于大多数实现都不使用TOS字段,因此像SLIP这种排队机制自己来判断和处理,驱动程序先查看协议段(确定是否是一个TCP段),然后检查TCP信源和信宿的端口号,以判断是否是一个交互服务。

    总长度(Total Length) 字段指整个IP数据报长度,以字节为单位。利用首部长度总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长度为16bit,所以IP数据报最大长度为 2161=65,5352^{16}-1=65,535 即,65,535字节。也就是最大传输单元(Maximum Transmission Unit,MTU) 为65,535字节。

    尽管可以传输最大65,535字节的数据报,但大多数链路层都会对它进行分片。而且主机也要求不能接收超过576字节的数据报。类似UDP的应用,它们限制用户数据报长度为512字节,小于576字节。

    事实上现在大多数的实现(特别是那些支持网络的文件系统NFS的实现)允许超过8192字节的IP数据报。

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

    RFC 791 [Postel 1981a]认为标识字段应该由让IP发送数据报的上层来选择。假设有两个连续的IP数据报,其中一个是由TCP生成的,而另一个是由UDP生成的,那么它们可能具有相同的标识字段。尽管这也可以照常工作(由重组算法来处理),但是在大多数从伯克利派生出来的系统中,每发送一个IP数据报,IP层都要把一个内核变量的值加1,不管交给IP的数据来自哪一层。内核变量的初始值根据系统引导时的时间来设置。

    TTL(time-to-live) 生存时间字段,设置了数据报可以经过的最多路由器数,指定了数据报的生存时间。初始值由源主机设置(通常为3264),经过一个处理它的路由器该值减1,当该值为0时,数据报被丢弃,并发送ICMP报文通知源主机。

    首部检验和(Header Checksum) 字段,根据IP首部计算的检验和码,它不对首部后面的数据进行计算。

    ICMPIGMPUDPTCP在它们各自的首部中均含有首部检验和码。

    为了计算一份数据报的IP检验和,首先将检验和字段置为0。然后,将首部中的数据按每16bit一块分成若干块(每块包含16位的原因是检验和正好是16位,这样便于将计算结果填充到对应的16位字段),对首部中每个16bit求和(注意当高位溢出时,需要低位回卷)后取反(即0变成1,1变成0)结果并存储到检验和字段中。

    第二种计算方法是,先将各字段二进制数据先取反,再求和。

    抓包数据

    Internet protocol Version 4, src: 192.168.0.109(192.168.0.109), Dst: 224.0.0.252(224.0.0.252)
    Version: 4
    Header length: 20bytes
    Differentiated Service field: 0x00 
    Total length: 71
    Identification: 0x1fd6 (8150)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 1
    Protocol: UDP (17)
    Header checksum: 0xf7be [correct]
    	[Good: True]
    	[Bad: False]
    Souce: 192.168.0.109
    Destination: 224.0.0.252
    

    结合上面抓包数据,发送方检验和计算步骤见下图:

    IP首部检验和计算步骤IP首部检验和计算步骤

    检验和求和前,首先将各字段各进制数值转换成二进制数值。如首部长度(Header length)数据报值为20bytes,先将其转换成十进制值为 32/8=4,20/4=532/8=4,20/4=5(行),然后再将5转成二进制101,由于首部长度占4bit,所以不足位补0,即0101

    求和时,当最高位需要进位时,进位被回卷到最低位。如上图虚线框结果,最高位1+1=101+1=10,只保留数值0,数值1回卷到最低位,即0+0+1=10+0+1=1,其中1就是高位回卷的数值。

    接收方校验数据步骤和发送方类似,区别在于接收方不再将检验和字段置为0,而是发送方计算好的值0xf7be1111011110111110,所以接收方最终计算结果为 0000100001000001+1111011110111110=11111111111111110000100001000001+1111011110111110=1111111111111111。如果结果每个比特位不全是1,那么IP将丢弃收到的数据报,但是不生成差错报文,由上层去发现丢失的数据报并进行重传。

    最后一个字段是可选字段,目前这些选项定义如下:

    • 安全和处理限制(用于军事领域,参见RFC 1108[Kent 1991])
    • 记录路径(让每个路由器都记录下它的IP地址)
    • 时间戳(让每个路由器都记录下它的IP地址和时间)
    • 宽松源站选路(为数据指定一系列必须经过的IP地址)
    • 严格源站选路(与宽松源站选路类似,但是要求只能经过指定的IP地址,不能经过其他地址)